来自同一 table 的多个插入,但第二个插入需要来自第一个插入的标识
Multiple inserts from same table, but 2nd insert needs identity from 1st insert
这是一个用来说明问题的人为示例:
我有一个存储过程需要插入这两个 tables
Person(ID_Person int identity, Forname varchar)
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
现在我们需要做的是 OUTPUT
在 INSERT
中创建的 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;
这是一个用来说明问题的人为示例:
我有一个存储过程需要插入这两个 tables
Person(ID_Person int identity, Forname varchar)
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
现在我们需要做的是 OUTPUT
在 INSERT
中创建的 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;