2010-04-06 106 views
1

我正在做一個SQL Insert來填充我的表。我在一個表中有一個唯一的生成的ID,我想在另一個表中使用我的連接。這可能嗎?我可以在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 

的代碼插入罰款。我如何將自動生成的PersonID拉到PRODUCT_DATA中使用?

+0

user54197看看松下的答案,我就可以了評論。如果有人在不知不覺中更改了您的存儲過程,則使用範圍標識返回PersonID存在一些潛在問題。 – msarchet 2010-04-06 15:29:01

+0

@msarchet:仔細闡述這些潛在問題是什麼?當然,如果有人可以在不知道它如何工作的情況下改變存儲過程,那麼可以破壞存儲過程,但這與SCOPE_IDENTITY本身無關 - 它們可能會破壞「OUTPUT INSERTED」子句。 – LukeH 2010-04-06 16:04:04

+0

剛纔你說的,這不是SCOPE_IDENTITY本身的問題,這很好。使用插入的輸出更加確定,因爲如果有人改變存儲過程的順序它不會中斷。這並不完美,因爲無論你如何返回價值,顯然有人可能會破壞你的SP。使用像'@variable int output'這樣的參數是獲取輸出最明顯的方法。但是仍然有人可以打破這一點,但這仍然很難。 – msarchet 2010-04-06 16:08:44

回答

3

您可以使用SCOPE_IDENTITY得到最後插入的標識值:

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

你可以在不使用SCOPE_IDENTITY()的情況下插入到兩個表中,並且在一個INSERT語句中查看我的答案:http://stackoverflow.com/questions/2585723/can-i-assign-a-variable-in -a-sql-stored-procedure/2585918#2585918 – 2010-04-06 15:17:57

+0

@KM:我知道你可以使用'OUTPUT INSERTED'子句用單個語句來完成它。一般而言,我發現單獨的陳述更具可讀性/可維護性:每項工作都有一個陳述。 – LukeH 2010-04-06 16:08:39

6

你並不需要使用SCOPE_IDENTITY(),使用輸出和一個單一的INSERT語句!
這確實需要SQL Server 2005和高達

試試這個:

設置表

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) 

創建過程

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 

測試代碼

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

輸出

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

同意使用作用域標識,直到有人更改存儲過程,導致返回的最後一個值不正確。哎呀 – msarchet 2010-04-06 15:27:57

+0

我以前沒見過,謝謝:-) – eftpotrm 2010-04-06 15:29:17

+0

這是一種將項目添加到日誌表的簡單方法。你甚至可以同時擁有多個OUTPUT語句。另外,如果你刪除了INTO,它將返回一個結果集。例如在'INTO Test2'和'VALUES'之間放置'OUTPUT INSERTED。*'。當你運行過程TestSP時,它將插入到兩個表中並返回一個包含Test1表的結果集(兩個'INSERT's和'SELECT'在一個'INSERT'內!)。 – 2010-04-06 15:41:15

相關問題