将SQL insert语句编写到另一个insert语句中

时间:2012-08-24 05:25:58

标签: tsql sql-server-2008-r2

我知道在T-SQL(Server 2008 R2)中,我可以使用'Output'关键字来获取刚刚插入的行的Id。例如,我可以做

insert into [Membership].[dbo].[User] (EmailAddress) 
output Inserted.UserId 
values('testUser1@test.com')

有没有办法把它组成另一个插页?例如,假设我想要添加新用户,并立即将该用户添加到UserRole表中,该表将UserId映射到RoleId

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

insert into UserRole (RoleId, UserId) 
values 
(
    1, 
    insert into [Membership].[dbo].[User] (EmailAddress) 
    output Inserted.UserId values('testUser1@test.com')
)

但我似乎无法让这个工作。我尝试将内部插入包装在方括号()中或使用select * from()等。

我错过了什么?这种构成甚至可能吗?

感谢您的帮助。

此致

2 个答案:

答案 0 :(得分:2)

您必须将输出捕获到表变量中:

DECLARE @TempVar TABLE (UserID INT)

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

然后在第二步中从该临时表中插入到目标表中:

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 ('testUser1@test.com')

答案 1 :(得分:0)

另一种解决方案是使用触发器:

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

并注意“after”插入触发器:

  

FOR | AFTER AFTER指定DML触发器仅在触发时触发   触发SQL语句中指定的所有操作都已执行   成功。所有参考级联操作和约束检查   在触发器触发之前也必须成功。

     

当FOR是唯一指定的关键字时,AFTER是默认值。

     

无法在视图上定义AFTER触发器。