2012-08-24 88 views
0

我知道在T-SQL(Server 2008 R2)中,我可以使用'Output'關鍵字來獲取剛剛插入的行的Id。例如,我可以做將SQL插入語句編寫到另一個插入語句中

insert into [Membership].[dbo].[User] (EmailAddress) 
output Inserted.UserId 
values('[email protected]') 

是否有任何方法將這個組合到另一個插入?例如,假設我想添加一個新用戶並立即將該用戶添加到UserRole表中,該表將UserId映射到RoleId

基本上,我想做下面的事情。

insert into UserRole (RoleId, UserId) 
values 
(
    1, 
    insert into [Membership].[dbo].[User] (EmailAddress) 
    output Inserted.UserId values('[email protected]') 
) 

但我似乎無法得到這個工作。我嘗試將括號內的內部插入()或使用select * from()等方式包裝起來。

我錯過了什麼?這個組成甚至可能嗎?

感謝您的幫助。

問候,

+0

你使用任何ORM? – FosterZ

回答

2

你將不得不捕獲輸出到一個表變量:

DECLARE @TempVar TABLE (UserID INT) 

insert into [Membership].[dbo].[User] (EmailAddress) 
output Inserted.UserId INTO @TempVar(UserID) 
values('[email protected]') 

,然後在第二個步驟做從臨時表插入到目標表:

INSERT INTO dbo.UserRole (RoleId, UserId) 
    SELECT 
     (yourRoleId), tv.UserID 
    FROM @TempVar tv 

您還可以將OUTPUT子句直接導入目標表 - 如果可以,例如使用固定的值,爲您RoleID

DECLARE @FixedRoleID INT = 42 

INSERT INTO [Membership].[dbo].[User] (EmailAddress) 
OUTPUT @FixedRoleID, Inserted.UserId INTO dbo.UserRole(RoleId, UserId) 
VALUES ('[email protected]') 
+0

我知道我可以使用臨時表,但我想知道是否有辦法將它從一個查詢組合成另一個查詢而沒有任何中間存儲。好像你最後的選擇就是這樣。 – Chaitanya

0

另一種解決方案是使用觸發器:

http://msdn.microsoft.com/en-us/library/ms189799.aspx

和 「之後」 注意insert觸發器:

FOR | AFTER AFTER指定只有在觸發SQL語句中指定的所有操作都已成功執行 時,觸發DML觸發器纔會觸發 。所有引用級聯操作和約束檢查 也必須在觸發器觸發前成功。

當FOR是唯一指定的關鍵字時,AFTER是默認值。

AFTER觸發器不能在視圖上定義。