我想在一个表中复制记录,改变一些值在SQL Server 2005中存储的过程。这是简单的,但我也需要与新的主键复制在其他表的关系。 由于这PROC被用来批量拷贝记录,我发现它难以储存旧键和新键之间的一些关系。 现在,我抓住使用输出转换成批量插入新的密钥。 例如:
INSERT INTO table
(column1, column2,...)
OUTPUT INSERTED.PrimaryKey INTO @TableVariable
SELECT column1, column2,...
有没有这样一种方式来轻松搞定,同时我将新钥匙插入旧密钥(以确保我已经配对适当的相应的键)?
我知道游标是一种选择,但我从来没有使用过,并只听到他们在一个恐怖故事的方式引用。 我更喜欢使用OUTPUT INTO,或类似的东西。
如果您需要在您的临时表来跟踪新老钥匙,你需要欺骗和使用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
滥用
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...
然后做你的INSERT
与OUTPUT
子句捕捉到你的新的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