2008-09-10 11 views
12

Dans SQL Server 2005, j'ai un champ "id" dans une table dont la propriété "Is Identity" est définie sur "Yes". Ainsi, lorsqu'un insert est exécuté sur cette table, "id" est automatiquement défini sur l'entier incrémenté suivant. Existe-t-il un moyen facile lorsque l'insertion est exécutée pour obtenir ce que "id" a été défini sans avoir à faire une instruction Select juste après l'insertion?Dans SQL Server, est-il possible d'obtenir "id" d'un enregistrement lorsque Insert est exécuté?

double de:
Best way to get identity of inserted row?

Répondre

32

Dans .Net au moins, vous pouvez envoyer plusieurs requêtes au serveur en une seule fois. Je le fais dans mon application:

command.CommandText = "INSERT INTO [Employee] (Name) VALUES (@Name); SELECT SCOPE_IDENTITY()"; 
int id = (int)command.ExecuteScalar(); 

Fonctionne comme un charme.

+3

Cette solution est bien quand traitant uniquement des mises à jour d'une seule ligne. Pour une bonne solution de mise à jour groupée, consultez la réponse de kamajo. – CodeWarrior

+1

Pour ceux qui cherchent à le faire avec MySQL: il suffit de remplacer SCOPE_IDENTITY par LAST_INSERT_ID. Ou utilisez simplement le paramètre LastInsertedId sur MySqlCommand; –

+0

Je reçois une erreur en renvoyant la valeur de retour de ExecuteScalar() directement à un int. Fonctionne bien lorsque je le lance en décimal. –

1

Vous devez sélectionner la fonction SCOPE_IDENTITY().

Pour ce faire, à partir du code de l'application, je encapsule normalement ce processus dans une procédure stockée afin qu'il ressemble toujours à une requête à mon application.

2

SCOPE_IDENTITY(); est votre meilleur pari. Et si vous utilisez .NET, transmettez simplement un de nos paramètres et vérifiez la valeur après l'exécution de la procédure.

CREATE PROCEDURE [dbo].[InsertProducts] 
    @id    INT    = NULL OUT, 
    @name   VARCHAR(150) = NULL, 
    @desc   VARCHAR(250) = NULL 

AS 

    INSERT INTO dbo.Products 
     (Name, 
     Description) 
    VALUES 
     (@name, 
     @desc) 

    SET @id = SCOPE_IDENTITY(); 
14

Si vous insérez plusieurs lignes, l'utilisation de la clause OUTPUT et INSERTED.columnname sur la déclaration insert est un moyen simple d'obtenir tous les ids dans une table temporaire.

DECLARE @MyTableVar table(ID int, 
           Name varchar(50), 
           ModifiedDate datetime); 
INSERT MyTable 
     OUTPUT INSERTED.ID, INSERTED.Name, INSERTED.ModifiedDate INTO @MyTableVar 
SELECT someName, GetDate() from SomeTable 
+0

J'aime ça! Merci pour le conseil. – CodeWarrior

+0

BTW, je ne sais pas si elle est spécifique à la version (c'est maintenant 2012 et je suis sur SQL 10.0.1600), mais vous n'avez pas à passer par une table temporaire pour cela - vous pouvez simplement produire directement. J'aime aussi que cela fonctionne aussi pour les champs GUID, s'ils sont utilisés comme PK ... pas que je préconise de le faire autant, mais ça marche. –

1

J'ai tendance à préférer attacher un déclencheur à la table en utilisant le gestionnaire d'entreprise. De cette façon, vous n'avez pas besoin de vous soucier d'écrire des instructions sql supplémentaires dans votre code. Le mien ressemble à quelque chose comme ceci:

Créer Trigger tblname Sur dbo.tblName Pour Insérer Comme sélectionnez new_id = @@ IDENTITY

Ensuite, à partir de votre code, traiter vos instructions d'insertion comme sélectionnez statements- Juste exécuter et évaluer les résultats. la colonne "newID" contiendra l'identité de la ligne que vous venez de créer.