来自同一 table 的多个插入,但第二个插入需要来自第一个插入的标识

Multiple inserts from same table, but 2nd insert needs identity from 1st insert

这是一个用来说明问题的人为示例:

我有一个存储过程需要插入这两个 tables

  1. Person(ID_Person int identity, Forname varchar)
  2. PersonExtension(ID_Person int, Age int)

它采用用户定义的 table 类型作为参数,因此我可以传递人员列表

create type ListOfPeople as table
(
    Forname varchar(20),
    Age int
)

我想插入 Person 和 PersonExtension,但第二次插入需要第一个的标识列

create procedure MyProcedure
    @ListOfPeople ListOfPeople readonly
as
begin
    insert into Person(Forname)
    select Forname from @ListOfPeople

    insert into PersonExtension(ID_Person, Age)
    select ?, Age from @ListOfPeople
end

如何有效地做到这一点?

我要假设你的table类型参数可以有多个行,因为缺少证据表明它不会,如果它只有 1 行,那么标量参数将是一个更好的选择。

首先,我们需要更改 table 类型参数的定义,因为我们需要行具有某种 ID:

CREATE TYPE dbo.ListOfPeople AS table (ID int IDENTITY, --defaults to 1,1
                                       Forename varchar(20), --Forename has an e in it
                                       Age int); --Storing the age of something is a really bad idea. Store their DoB

现在我们需要做的是 OUTPUTINSERT 中创建的 IDENTITY 值的值以及来自您的 ID 的值table 类型参数,并将其插入到 table 变量中。在 T-SQL 中,您不能 OUTPUT 不属于 INSERT 的列。您 可以 ,但是,请使用 MERGE。然后我们可以使用值插入执行一个JOIN并得到值:

CREATE PROC dbo.MyProcedure @ListOfPeople dbo.ListOfPeople READONLY AS
BEGIN

    DECLARE @Persons table (ID int, PID int);

    MERGE INTO Person USING @ListOfPeople AS LOP ON 1 = 0
    WHEN NOT MATCHED THEN
        INSERT (forename)
        VALUES (LOP.forename)
        OUTPUT LOP.ID, inserted.ID --Assumed Person's ID column is ID
        INTO @Persons (ID, PID);

    INSERT INTO dbo.PersonExtension(ID_Person,Age) --Again, storing Age is a bad idea
    SELECT P.PID,
           LOP.Age
    FROM @Persons P
         JOIN @ListOfPeople LOP ON P.ID = LOP.ID;

END;