2010-04-06 7 views
1

Je crée un SQL Insert pour remplir ma table. J'ai un ID généré unique dans une table que je voudrais utiliser dans une autre table pour ma jointure. Est-ce possible?Puis-je attribuer une variable dans une procédure stockée SQL?

.NET MVC -

using (SqlConnection connect = new SqlConnection(connections)) 
{ 
    SqlCommand command = new SqlCommand("ContactInfo_Add", connect); 
    command.Parameters.Add(new SqlParameter("name", name)); 
    command.Parameters.Add(new SqlParameter("address", address)); 
    command.Parameters.Add(new SqlParameter("Product", name)); 
    command.Parameters.Add(new SqlParameter("Quantity", address)); 
    command.Parameters.Add(new SqlParameter("DueDate", city)); 
    connect.Open(); 
    command.ExecuteNonQuery(); 
} 

SQL SERVER -

ALTER PROCEDURE [dbo].[Contact_Add] 
@name varchar(40), 
@address varchar(60), 
@Product varchar(40), 
@Quantity varchar(5), 
@DueDate datetime 
AS 
BEGIN 
    SET NOCOUNT ON; 

    INSERT INTO DBO.PERSON 
    (Name, Address) VALUES (@name, @address) 
    INSERT INTO DBO.PRODUCT_DATA 
    (PersonID, Product, Quantity, DueDate) VALUES (@Product, @Quantity, @DueDate) 
END 

Le code insère bien. Juste comment puis-je tirer le PersonID généré automatiquement à utiliser dans PRODUCT_DATA?

+0

user54197 regarder la réponse de KM et mon commentaire à ce sujet. L'utilisation de Scope Identity peut générer des problèmes pour renvoyer le PersonID si quelqu'un modifie sans le savoir la procédure de votre magasin. – msarchet

+0

@msarchet: Vous voulez en savoir plus sur ces problèmes potentiels? Bien sûr, quelqu'un peut casser votre procédure stockée s'il la change sans savoir comment cela fonctionne, mais cela n'a rien à voir avec 'SCOPE_IDENTITY' lui-même - ils sont tout aussi susceptibles de casser une clause' OUTPUT INSERTED'. – LukeH

+0

Exactement ce que vous venez de dire, ce n'est pas un problème avec SCOPE_IDENTITY lui-même, cela fonctionne très bien. Il y a juste plus de certitude sur l'utilisation de la sortie insérée car elle ne se casse pas si quelqu'un change l'ordre de la procédure stockée. Ce n'est pas parfait car il est évident que quelqu'un pourrait toujours casser votre SP, peu importe comment vous retournez une valeur. L'utilisation d'un paramètre comme '@variable int output' est la façon la plus évidente d'obtenir une sortie. Mais quelqu'un peut encore casser cela, mais c'est encore plus difficile. – msarchet

Répondre

3

Vous pouvez utiliser SCOPE_IDENTITY pour obtenir la dernière valeur d'identité insérée:

DECLARE @PersonID INT 

INSERT INTO dbo.Person (Name, Address) 
VALUES (@Name, @Address) 

SET @PersonID = SCOPE_IDENTITY() 

INSERT INTO dbo.Product_Data (PersonID, Product, Quantity, DueDate) 
VALUES (@PersonID, @Product, @Quantity, @DueDate) 
+0

vous pouvez insérer dans les deux tables sans utiliser SCOPE_IDENTITY() et dans une instruction INSERT unique, consultez ma réponse pour comment: http://stackoverflow.com/questions/2585723/can-i-assign-a-variable-in -a-sql-stored-procedure/2585918 # 2585918 –

+0

@KM: Je suis conscient que vous pouvez le faire avec une seule instruction en utilisant une clause 'OUTPUT INSERTED'. En général, je trouve les déclarations séparées plus lisibles/maintenable: une déclaration pour chaque travail. – LukeH

6

Vous n'avez pas besoin d'utiliser SCOPE_IDENTITY(), utilisez la sortie et une seule instruction INSERT!
cela nécessite SQL Server 2005 et jusqu'à

Essayez ceci:

configurer les tables

CREATE TABLE Test1 (PersonID int identity(1,1), Name varchar(40), Address varchar(60)) 
CREATE TABLE Test2 (PersonID int, product varchar(40),Quantity varchar(5),DueDate datetime) 

créer la procédure

CREATE PROCEDURE TestSP 
@name varchar(40), 
@address varchar(60), 
@Product varchar(40), 
@Quantity varchar(5), 
@DueDate datetime 
AS 
BEGIN 
    SET NOCOUNT ON; 

    INSERT INTO Test1 
      (Name, Address) 
      OUTPUT INSERTED.PersonID, @Product, @Quantity, @DueDate 
      INTO Test2 
     VALUES 
      (@name, @address) 

END 

tester le code

exec TestSP 'name','address','product',123,'1/1/2010' 
select * from Test1 
select * from Test2 

sortie

PersonID Name     Address 
----------- -------------------- ----------------------- 
1   name     address 

(1 row(s) affected) 

PersonID product Quantity DueDate 
----------- --------- -------- ----------------------- 
1   product 123  2010-01-01 00:00:00.000 

(1 row(s) affected) 
+0

D'accord à l'aide de l'identité de l'étendue fonctionne jusqu'à ce que quelqu'un modifie votre procédure stockée causant la dernière valeur renvoyée à ne pas être la bonne. Oups – msarchet

+0

Je ne l'avais pas vu avant, merci :-) – eftpotrm

+0

c'est un moyen facile d'ajouter des éléments à une table de journal. Vous pouvez même avoir plusieurs instructions OUTPUT à la fois. En outre, si vous supprimez le INTO il renvoie un ensemble de résultats. par exemple, mettez 'OUTPUT INSERTED. *' entre 'INTO Test2' et' VALUES'. lorsque vous exécutez la procédure TestSP, il va insérer dans les deux tables et retourner un jeu de résultats contenant la table Test1 (deux 'INSERT's et un' SELECT' dans un 'INSERT'!). –

Questions connexes