我可以保留在SQL制作副本时链接到新的密钥旧密钥?(Can I keep old keys link

2019-09-01 16:38发布

我想在一个表中复制记录,改变一些值在SQL Server 2005中存储的过程。这是简单的,但我也需要与新的主键复制在其他表的关系。 由于这PROC被用来批量拷贝记录,我发现它难以储存旧键和新键之间的一些关系。 现在,我抓住使用输出转换成批量插入新的密钥。 例如:

INSERT INTO table
 (column1, column2,...)
 OUTPUT INSERTED.PrimaryKey INTO @TableVariable
 SELECT column1, column2,...

有没有这样一种方式来轻松搞定,同时我将新钥匙插入旧密钥(以确保我已经配对适当的相应的键)?

我知道游标是一种选择,但我从来没有使用过,并只听到他们在一个恐怖故事的方式引用。 我更喜欢使用OUTPUT INTO,或类似的东西。

Answer 1:

如果您需要在您的临时表来跟踪新老钥匙,你需要欺骗和使用MERGE

数据设置:

create table T (
    ID int IDENTITY(5,7) not null,
    Col1 varchar(10) not null
);
go
insert into T (Col1) values ('abc'),('def');

而更换为您的INSERT语句:

declare @TV table (
    Old_ID int not null,
    New_ID int not null
);
merge into T t1
using (select ID,Col1 from T) t2
on 1 = 0
when not matched then insert (Col1) values (t2.Col1)
output t2.ID,inserted.ID into @TV;

和(实际上需要在同一批次,这样就可以访问表变量):

select * from T;
select * from @TV;

生产:

ID  Col1
5   abc
12  def
19  abc
26  def

Old_ID  New_ID
5       19
12      26

你必须这样做的原因是因为在一个刺激性限制的OUTPUT子句当用于INSERT -你只能访问inserted的不是任何这可能是一个组成部分表格表, SELECT


相关-的更多解释MERGE滥用



Answer 2:

INSERT语句将数据加载到与表IDENTITY列都保证以相同的顺序为,以产生值ORDER BY在子句SELECT

如果你想在下面的顺序在ORDER BY子句顺序的方式来分配的IDENTITY值,创建一个包含与IDENTITY属性的列一个表,然后运行一个INSERT ... SELECT ... ORDER BY查询来填充此表。

来源: 与SELECT INTO或INSERT使用时,IDENTITY函数的行为。选择包含ORDER BY子句的查询

你可以利用这一点来匹配您的旧与新的标识值。 首先收集您想复制到一个临时表的主键的列表。 您还可以包括修改后的列值,以及如果需要的话:

select
    PrimaryKey,
    Col1
    --Col2... etc
into #NewRecords
from Table
--where whatever...

然后做你的INSERTOUTPUT子句捕捉到你的新的ID到表变量:

declare @TableVariable table (
    New_ID int not null
);

INSERT INTO #table
    (Col1 /*,Col2... ect.*/)
OUTPUT INSERTED.PrimaryKey INTO @NewIds
SELECT Col1 /*,Col2... ect.*/
from #NewRecords
order by PrimaryKey

由于的ORDER BY PrimaryKey语句,你将得到保证,你的New_ID数字将在相同的顺序生成PrimaryKey的复制的记录字段。 现在,您可以通过该ID值排序行号匹配起来。 下面的查询会给你的碎料:

select PrimaryKey, New_ID
from
    (select PrimaryKey, 
        ROW_NUMBER() over (order by PrimaryKey) OldRow
    from #NewRecords
    ) PrimaryKeys
join
    (
    select New_ID, 
        ROW_NUMBER() over (order by New_ID) NewRow
    from @NewIds
    ) New_IDs
on OldRow = NewRow


文章来源: Can I keep old keys linked to new keys when making a copy in SQL?