如何在插入后进行插入并将数据与第一次插入的结果 ID 组合

How to make insert after insert and combine data with result ID's from first insert

DECLARE @tmpTable TABLE (UserId INT, Name nvarchar(50), Department nvarchar(50))
DECLARE @xml XML=
N'<user><userId>1</userId><name>John</name><department>A</department></user>
<user><userId>2</userId><name>Jane</name><department>B</department></user>';
insert into @tmpTable
SELECT 
    a.b.value('(./userId)[1]', 'int') AS UserId,
    a.b.value('(./name)[1]', 'nvarchar(50)') AS Name,
    a.b.value('(./department)[1]', 'nvarchar(50)') AS Department
FROM @xml.nodes('/user') a(b)
INSERT INTO members (name)
OUTPUT Inserted.MemberId
SELECT Name FROM @tmpTable

现在输出新成员的 ID。 我需要对另一个 table 进行另一个插入,这需要:

MemberId, UserId, Name, Department

我不知道怎么写这个插页。

您需要 record/track 在第一次插入时创建的 IDENTITY ID。 但是您需要以基于 SET 的方式进行跟踪。 (我认为你只用“OUTPUT Inserted.MemberId”跟踪单个项目)

给你:

DECLARE @tmpTable TABLE (UserId INT, Name nvarchar(50), Department nvarchar(50))
DECLARE @xml XML=
N'<user><userId>1</userId><name>John</name><department>A</department></user>
<user><userId>2</userId><name>Jane</name><department>B</department></user>';
insert into @tmpTable
SELECT 
    a.b.value('(./userId)[1]', 'int') AS UserId,
    a.b.value('(./name)[1]', 'nvarchar(50)') AS Name,
    a.b.value('(./department)[1]', 'nvarchar(50)') AS Department
FROM @xml.nodes('/user') a(b)


create table #AUDIT ( EntityKey int not null default -1  ,  OldMyName varchar(128)  null, NewMyName varchar(128)  null , Tag varchar(64)  );



CREATE TABLE #MEMBERSREALTABLEMIMIC (MyIdentity INT IDENTITY (3001, 3) , MyName varchar(128) )

/* replace my #MEMBERSREALTABLEMIMIC with your real dbo.Member table here..i had to fake it since I don't have the DDL to dbo.Member */
INSERT INTO #MEMBERSREALTABLEMIMIC (MyName)
output inserted.MyIdentity , null , inserted.MyName , 'Employee Inserted' into #AUDIT ( EntityKey , OldMyName , NewMyName , Tag)
SELECT Name FROM @tmpTable


Select * from #MEMBERSREALTABLEMIMIC
Select * from #AUDIT


DROP table #MEMBERSREALTABLEMIMIC
DROP table #AUDIT

您可以使用#AUDIT table 插入其他 tables.. 因为您现在有 IDENTITY 的记录。 (有相应的名字)。

请注意,如果“MyName”没有唯一约束,这可能会失败。

您“审核”INSERT 的原因是为了避免为新 IDENTITY 命中 dbo.Member table....(假设您在 dbo.Member table...审计将阻止重新查看 table)

https://granadacoder.wordpress.com/2008/12/10/sqlserver20052008-output-clause-in-insertupdatedelete-statements/

这是一个例子:

create table PrimaryHolderTable ( i int identity (1001,2) not null primary key, j int not null unique )
create table #OutputResultsHolder ( i int not null, j int not null)
 
insert into PrimaryHolderTable (j)
output inserted.i, inserted.j into #OutputResultsHolder
select top 10 o.object_id from sys.objects as o order by o.object_id desc --<< from sys.objects is there just to provide some rows
 

select * from #OutputResultsHolder
drop table #OutputResultsHolder, PrimaryHolderTable;

go
 
 

create table dbo.EmployeeTable ( EmpKey int identity(1001,2) ,  EmpAge int not null );
create table dbo.AuditTable ( EntityKey int not null default -1  ,  OldValue int null, NewValue int null , Tag varchar(64)  );
 
insert into dbo.EmployeeTable (EmpAge)
output inserted.EmpKey , null , inserted.EmpAge , 'Employee Inserted' into dbo.AuditTable ( EntityKey , OldValue , NewValue , Tag)
 values( 18 );

insert into dbo.EmployeeTable (EmpAge)
output inserted.EmpKey , null , inserted.EmpAge , 'Employee Inserted' into dbo.AuditTable ( EntityKey , OldValue , NewValue , Tag)
 values( 20 );

insert into dbo.EmployeeTable (EmpAge)
output inserted.EmpKey , null , inserted.EmpAge , 'Employee Inserted' into dbo.AuditTable ( EntityKey , OldValue , NewValue , Tag)
 values( 22 );
 
 
update dbo.EmployeeTable
   set EmpAge  = EmpAge + 1
output inserted.EmpKey , deleted.EmpAge, inserted.EmpAge , 'Employee Updated' into dbo.AuditTable ( EntityKey , OldValue , NewValue , Tag)
 where EmpAge <=20;
 
delete from dbo.EmployeeTable
output deleted.EmpKey , deleted.EmpAge, NULL , 'Employee Deleted'  into dbo.AuditTable (EntityKey , OldValue , NewValue , Tag)
 where EmpAge > 0;  --Test multi rows
 
select * from dbo.EmployeeTable;   --<<will be empty at this point
select * from dbo.AuditTable;
 
drop table dbo.EmployeeTable, dbo.AuditTable;
go

追加

请注意,您不能“跳过”#AUDIT Table。 #AUDIT Table 只能包含来自您的 PARENT INSERT 的信息片段(您拥有的任何属性,当然还有您想要的新 IDENTITY)

这就是我认为您想要的。 (使用 fiddle)

drop table tbl_tourSequence;
drop table tbl_tours;


create table tbl_tours (
  tourId int NOT NULL IDENTITY (1001, 5) PRIMARY KEY, 
  timeFrom smalldatetime
);
create table tbl_tourSequence (
  tourSequenceId int NOT NULL IDENTITY (2002, 3) PRIMARY KEY, 
  tour_fk int, 
  dispatchId int, 
  timeFrom smalldatetime, 
  timeTo smalldatetime
);


DECLARE @tmpTable TABLE (DispatchingId INT, TimeFrom smalldatetime, TimeTo smalldatetime)
DECLARE @xml XML=
N'<dispatch><dispatchingId>-1</dispatchingId><timeFrom>2020-07-28T07:00:00.000Z</timeFrom><timeTo>2020-07-28T07:00:00.000Z</timeTo></dispatch>
<dispatch><dispatchingId>10</dispatchingId><timeFrom>2020-07-28T07:00:00.000Z</timeFrom><timeTo>2020-07-28T07:00:00.000Z</timeTo></dispatch>

<dispatch><dispatchingId>-22</dispatchingId><timeFrom>2010-01-28T07:00:00.000Z</timeFrom><timeTo>2020-07-28T07:00:00.000Z</timeTo></dispatch>
<dispatch><dispatchingId>220</dispatchingId><timeFrom>2010-01-28T07:00:00.000Z</timeFrom><timeTo>2020-07-28T07:00:00.000Z</timeTo></dispatch>




';
insert into @tmpTable
SELECT 
    t.p.value('(./dispatchingId)[1]', 'int') AS DispatchingId,
    t.p.value('(./timeFrom)[1]', 'smalldatetime') AS TimeFrom,
    t.p.value('(./timeTo)[1]', 'smalldatetime') AS TimeTo
FROM @xml.nodes('/dispatch') t(p)


SELECT * FROM @tmpTable

create table #PARENTAUDIT ( EntityKey int not null default -1  ,  OldTimeFrom smalldatetime  null, NewTimeFrom smalldatetime null , Tag varchar(64)  );

INSERT INTO tbl_tours (TimeFrom)
output inserted.tourId , null , inserted.TimeFrom , 'TOUR Inserted' into #PARENTAUDIT ( EntityKey , OldTimeFrom , NewTimeFrom , Tag)
SELECT DISTINCT TimeFrom FROM @tmpTable

/* NOTE THE DISTINCT ABOVE, this solution depends on some unique contraint that maps the parents and the children.  here we use TimeFrom */


SELECT '#PARENTAUDIT' , * from #PARENTAUDIT


INSERT INTO tbl_tourSequence ( tour_fk , dispatchId , timeFrom , timeTo )
SELECT pa.EntityKey , tt.DispatchingId , tt.TimeFrom , tt.TimeTo
FROM #PARENTAUDIT pa JOIN @tmpTable tt on pa.NewTimeFrom = tt.TimeFrom



DROP TABLE  #PARENTAUDIT 


Select * from tbl_tours

Select * from tbl_tourSequence