Componer una declaración de inserción de SQL en otra declaración de inserción

I know that in T-SQL (Server 2008 R2) I can use the 'Output' keyword to get the Id of a row I just inserted. For example, I can do

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

Is there any way of composing this into another insert? For example, lets say I want to add a new user and immediately add that user to a UserRole table which maps the UserId a una RoleId.

Basically, I would like to do something like below.

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

But I can't seem to get this to work. I tried wrapping the internal insert in brackets () or using a select * from () etc.

What am I missing? Is this composition even possible?

Gracias por la ayuda.

Saludos,

preguntado el 24 de agosto de 12 a las 06:08

2 Respuestas

You would have to capture the output into a table variable:

DECLARE @TempVar TABLE (UserID INT)

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

and then in a second step do an insert from that temp table into the target table:

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

You could also direct the OUTPUT clause directly into the target table - that'll work if you can e.g. use a fixed value for your RoleID:

DECLARE @FixedRoleID INT = 42

INSERT INTO [Membership].[dbo].[User] (EmailAddress) 
OUTPUT @FixedRoleID, Inserted.UserId INTO dbo.UserRole(RoleId, UserId)
VALUES ('testUser1@test.com')

Respondido 24 ago 12, 06:08

I knew I could have used temporary tables, but I wanted to see if there was a way to compose it from one query to another without any intermediate storage. Seems like your last option does exactly that. - Chaitanya

Another solution is to use triggers:

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

and pay attention to "after" insert triggers:

FOR | AFTER AFTER specifies that the DML trigger is fired only when all operations specified in the triggering SQL statement have executed successfully. All referential cascade actions and constraint checks also must succeed before this trigger fires.

AFTER es el valor predeterminado cuando FOR es la única palabra clave especificada.

DESPUÉS de que los activadores no se pueden definir en las vistas.

Respondido 24 ago 12, 09:08

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.