SQL Server-valeur de retour après insertion
J'essaie de récupérer une valeur clé après une instruction INSERT. Exemple: J'ai une table avec le nom et l'id des attributs. id est une valeur générée.
INSERT INTO table (name) VALUES('bob');
Maintenant, je veux récupérer l'id dans la même étape. Comment est-ce fait?
Nous utilisons Microsoft SQL Server 2008.
10 réponses
Pas besoin d'une sélection séparée...
INSERT INTO table (name)
OUTPUT Inserted.ID
VALUES('bob');
Cela fonctionne aussi pour les colonnes non-IDENTITY (telles que les GUID)
Utilisez SCOPE_IDENTITY()
pour obtenir la nouvelle valeur D'ID
INSERT INTO table (name) VALUES('bob');
SELECT SCOPE_IDENTITY()
INSERT INTO files (title) VALUES ('whatever');
SELECT * FROM files WHERE id = SCOPE_IDENTITY();
Est le pari le plus sûr car il existe un problème connu avec le conflit de Clause de sortie sur les tables avec des déclencheurs. Cela rend cela assez peu fiable car même si votre table n'a actuellement aucun déclencheur-quelqu'un en ajoutant un sur la ligne va casser votre application. Une sorte de comportement de bombe à retardement.
Voir l'article msdn pour plus d'explications:
Entity Framework effectue quelque chose de similaire à la réponse de gbn:
DECLARE @generated_keys table([Id] uniqueidentifier)
INSERT INTO Customers(FirstName)
OUTPUT inserted.CustomerID INTO @generated_keys
VALUES('bob');
SELECT t.[CustomerID]
FROM @generated_keys AS g
JOIN dbo.Customers AS t
ON g.Id = t.CustomerID
WHERE @@ROWCOUNT > 0
Les résultats de sortie sont stockés dans une variable de table temporaire,puis sélectionnés dans le client. Je dois être conscient du gotcha:
Insère peut produire plus d'une ligne, de sorte que la variable peut contenir plus d'une ligne, de sorte que vous pouvez être retourné plus d'un
ID
Je n'ai aucune idée de pourquoi EF serait intérieur rejoindre la table éphémère à la table réelle (dans quelles circonstances le à deux pas de match).
Mais C'est ce que fait EF.
SQL Server 2008 ou plus récent uniquement. Si nous sommes en 2005, alors vous n'avez pas de chance.
@ @ IDENTITY est une fonction système qui renvoie la dernière valeur d'identité insérée.
Vous pouvez utiliser scope_identity pour sélectionner l'ID de la ligne que vous venez d'insérer dans une variable, puis sélectionnez simplement les colonnes que vous voulez dans cette table où l'id = l'identité que vous avez obtenue de scope_identity
Voir ici pour les informations MSDN http://msdn.microsoft.com/en-us/library/ms190315.aspx
Voici comment j'utilise la sortie insérée, lors de l'insertion dans une table qui utilise ID comme colonne d'identité dans SQL Server:
'myConn is the ADO connection, RS a recordset and ID an integer
Set RS=myConn.Execute("INSERT INTO M2_VOTELIST(PRODUCER_ID,TITLE,TIMEU) OUTPUT INSERTED.ID VALUES ('Gator','Test',GETDATE())")
ID=RS(0)
Vous pouvez ajouter une instruction select à votre instruction insert. Entier myInt = Insert into table1 (FName) values ("Fred"); Sélectionnez Scope_Identity(); Cela renvoie la valeur de l'identité lors de l'exécution scaler.
* l'ordre des paramètres dans la chaîne de connexion est parfois important. * l'emplacement du paramètre fournisseur peut casser le curseur recordset après avoir ajouté une ligne. Nous avons vu ce comportement avec le fournisseur SQLOLEDB.
Après l'ajout d'une ligne, les champs de ligne ne sont pas disponibles, sauf si le fournisseur est spécifié comme premier paramètre dans la chaîne de connexion. Lorsque le fournisseur est n'importe où dans la chaîne de connexion, sauf en tant que premier paramètre, les champs de ligne nouvellement insérés sont pas disponibles. Lorsque nous avons déplacé le fournisseur vers le premier paramètre, les champs de ligne sont apparus comme par magie.
Après avoir effectué une insertion dans une table avec une colonne d'identité, vous pouvez référencer @ @ IDENTITY pour obtenir la valeur: http://msdn.microsoft.com/en-us/library/aa933167%28v=sql.80%29.aspx