2012-08-24 39 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触发器不能在视图上定义。