2009-09-02 12 views
1

J'ai une requête qui met à jour un enregistrement et un seul enregistrement. Est-il possible de mettre l'ID à jour dans la même requête, telle que Select ScopeIdentity lors de l'insertion.Mise à jour Ligne

UPDATE Task 
SET MyTime = GetDate(), MyUserId = @userid 
FROM (select top 1 table where SomeStuff) 

Select Lastrow that just got updated. 
+0

Alors vous savez que vous mettez à jour exactement un enregistrement, mais vous ne saurez pas lequel avant sa mise à jour? – MartW

Répondre

2

En fonction de ce que vous faites, vous devrez peut-être utiliser la syntaxe de table OUTPUT. Une possibilité est de spécifier une variable table/table temporaire.

DECLARE @T TABLE 
(
    MyID INT NOT NULL 
) 

UPDATE Task 
SET MyTime = GetDate(), MyUserId = @userid 
OUTPUT INSERTED.MyID INTO @T 
FROM (/* your FROM clause here */) Task 

gbn a obtenu une modification en avant de moi qui dit essentiellement la même chose que ci-dessus. Je voudrais ajouter qu'une autre façon de le faire est de saisir l'ID d'abord, puis de mettre à jour par ID. En outre, TOP 1 devrait presque toujours être utilisé avec un ORDER BY.

-- You may need to clean up the error handling. I just wanted 
-- to put something simple in to remind that it is necessary. 
DECLARE @userid INT; SET @userid = /* e.g., */ 1234 
BEGIN TRANSACTION 
IF @@ERROR <> 0 RETURN 
DECLARE @TaskID INT 
SET @TaskID = (SELECT TOP 1 TaskID FROM Task WITH (UPDLOCK) ORDER BY /* e.g., */ TaskID) -- TaskID should be the PK of MyTable. Must be unique. 
IF @@ERROR <> 0 BEGIN ROLLBACK TRANSACTION RETURN END 
UPDATE Task 
SET MyTime = GETDATE(), MyUserId = @userid 
WHERE TaskID = @TaskID 
COMMIT TRANSACTION 
+0

Merci pour la bonne réponse! Il y a un ordre par je ne l'ai pas inclus :) –

+0

Pourquoi avez-vous besoin de UPDLOCK? Nous avons déjà des problèmes de blocage, donc cela ne va pas augmenter en utilisant UPDLOCK –

+0

UPDLOCK: Dans ce cas, pas nécessaire si vous utilisez le niveau d'isolation REPEATABLE READ ou SERIALIZABLE. Sinon, cela garantit qu'un autre utilisateur ne peut pas sauter et mettre à jour (ou même supprimer!) La ligne dans la courte période entre les instructions SELECT et UPDATE. Cela n'a peut-être pas d'importance dans votre cas, mais je pense que c'est une bonne pratique d'indiquer que vous faites un "SELECT avec l'intention de mettre à jour". Souvent, cela réduira les blocages, mais cela dépendra du cas par cas. –

4

Oui, utilisez la OUTPUT clause

Exemple:

UPDATE Task 
SET MyTime = GetDate(), MyUserId = @userid 
OUTPUT INSERTED.MyID 
FROM (select top 1 table where SomeStuff) 

ou

DECLARE @MyTableVar TABLE (... 

... 
UPDATE Task 
SET MyTime = GetDate(), MyUserId = @userid 
OUTPUT INSERTED.MyID INTO @MyTableVar 
FROM (select top 1 table where SomeStuff) 
+0

Vraiment très bonne réponse! –