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

6l7fqoea  于 2021-07-29  发布在  Java
关注(0)|答案(1)|浏览(372)
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。我需要对另一个表进行另一次插入,这需要:

MemberId, UserId, Name, Department

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

pnwntuvh

pnwntuvh1#

您需要记录/跟踪在第一次插入时创建的标识id。但你需要以一种固定的方式来追踪(你只跟踪了一个带有“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表插入到其他表中..因为您现在有标识的记录(具有相应的名称)。
请注意,如果“myname”上没有唯一的约束,这可能会崩溃。
“审核”插入的原因是为了避免在dbo.member表中找到新标识……(假设dbo.member表中已经有1000000行……,审核将防止重新查找该表)
看见
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表只能包含父insert中的部分信息(您拥有的任何属性,当然还有新的标识,这是您所追求的)
这是我想你要找的((使用小提琴)

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

相关问题