我想用SQL编写脚本,该脚本会将这2个表(A,B)复制到其他2个表(C,D),并具有与A,B相同的结构。
重要提示 :
表A具有表B的外键(fk_a_b)
________________________ _________________ | Table A | | Table B | |______________________| |_______________| | id FK_A_B name | | id visible | | ----- -------- ------| | ----- --------| | 1 21 n1 | | 21 true | | 5 32 n2 | | 32 false | ------------------------ -----------------
假设将表B复制到D之后,这就是我得到的
________________ | Table D | |______________| | id visible | | ----- -------| | 51 true | | 52 false | ----------------
现在,当我将表A复制到CI时,需要知道,ID = 21现在映射到ID = 51,ID = 32映射到ID = 52。最后,表C将为:
________________________ | Table C | |______________________| | id FK_C_D name | | ----- -------- ------| | 61 51 n1 | | 62 52 n2 | ------------------------
由于多个进程可能同时调用脚本,因此我无法更改表A,B来添加一些帮助程序列。因此,为了达到这个目的,我使用了CURSOR。我逐行复制表B和托管临时表以将OldId映射到NewId(21-> 51,32-> 52),然后使用此临时表复制表A。
我读过CURSOR是不好的做法。那么,还有另一种方法吗?
谢谢
您可以将output子句与merge语句一起使用,以获取源ID和目标ID之间的映射。
这是您可以测试的一些代码。我使用表变量而不是实际表。
设置样本数据:
-- @A and @B is the source tables declare @A as table ( id int, FK_A_B int, name varchar(10) ) declare @B as table ( id int, visible bit ) -- Sample data in @A and @B insert into @B values (21, 1),(32, 0) insert into @A values (1, 21, 'n1'),(5, 32, 'n2') -- @C and @D is the target tables with id as identity columns declare @C as table ( id int identity, FK_C_D int not null, name varchar(10) ) declare @D as table ( id int identity, visible bit ) -- Sample data already in @C and @D insert into @D values (1),(0) insert into @C values (1, 'x1'),(1, 'x2'),(2, 'x3')
复制数据:
-- The @IdMap is a table that holds the mapping between -- the @B.id and @D.id (@D.id is an identity column) declare @IdMap table(TargetID int, SourceID int) -- Merge from @B to @D. merge @D as D -- Target table using @B as B -- Source table on 0=1 -- 0=1 means that there are no matches for merge when not matched then insert (visible) values(visible) -- Insert to @D output inserted.id, B.id into @IdMap; -- Capture the newly created inserted.id and -- map that to the source (@B.id) -- Add rows to @C from @A with a join to -- @IdMap to get the new id for the FK relation insert into @C(FK_C_D, name) select I.TargetID, A.name from @A as A inner join @IdMap as I on A.FK_A_B = I.SourceID
结果:
select * from @D as D inner join @C as C on D.id = C.FK_C_D id visible id FK_C_D name ----------- ------- ----------- ----------- ---------- 1 1 1 1 x1 1 1 2 1 x2 2 0 3 2 x3 3 1 4 3 n1 4 0 5 4 n2