在SQL中创建副本时,是否可以将旧密钥链接到新密钥?
我正在尝试复制表中的一条记录,并使用SQLServer2005中的存储过程更改一些值。这很简单,但我还需要使用新的主键复制其他表中的关系。由于此过程用于批量复制记录,我发现很难存储旧密钥和新密钥之间的某些关系。 现在,我正在使用OUTPUT-INTO从批插入中获取新密钥。 例: 有没有这样的方法可以在插入新钥匙的同时轻松地插入旧钥匙,以确保正确的对应钥匙配对在SQL中创建副本时,是否可以将旧密钥链接到新密钥?,sql,sql-server,primary-key,output,Sql,Sql Server,Primary Key,Output,我正在尝试复制表中的一条记录,并使用SQLServer2005中的存储过程更改一些值。这很简单,但我还需要使用新的主键复制其他表中的关系。由于此过程用于批量复制记录,我发现很难存储旧密钥和新密钥之间的某些关系。 现在,我正在使用OUTPUT-INTO从批插入中获取新密钥。 例: 有没有这样的方法可以在插入新钥匙的同时轻松地插入旧钥匙,以确保正确的对应钥匙配对 我知道游标是一种选择,但我从未使用过它们,只听到它们以恐怖故事的方式被引用。我更喜欢使用输出到或类似的东西。如果需要跟踪临时表中的新旧键,
我知道游标是一种选择,但我从未使用过它们,只听到它们以恐怖故事的方式被引用。我更喜欢使用输出到或类似的东西。如果需要跟踪临时表中的新旧键,则需要欺骗并使用合并: 数据设置:
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;
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
产生:
ID Col1
5 abc
12 def
19 abc
26 def
Old_ID New_ID
5 19
12 26
您必须这样做的原因是,当与INSERT一起使用时,对的限制令人恼火-您只能访问插入的表,而不能访问任何可能属于SELECT的表
如果需要跟踪临时表中的新旧键,则需要作弊并使用合并: 数据设置:
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;
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
产生:
ID Col1
5 abc
12 def
19 abc
26 def
Old_ID New_ID
5 19
12 26
您必须这样做的原因是,当与INSERT一起使用时,对的限制令人恼火-您只能访问插入的表,而不能访问任何可能属于SELECT的表
将数据加载到具有标识列的表中的INSERT语句保证以与SELECT中order BY子句相同的顺序生成值
如果希望以顺序方式指定标识值
在ORDERBY子句中的排序之后,创建一个
包含具有IDENTITY属性的列,然后运行INSERT。。
选择…按查询排序以填充此表
发件人:
您可以使用此事实将旧标识值与新标识值相匹配。首先收集要复制到临时表中的主键列表。如果需要,还可以包括修改的列值:
select
PrimaryKey,
Col1
--Col2... etc
into #NewRecords
from Table
--where whatever...
然后使用OUTPUT子句执行INSERT,以将新ID捕获到表变量中:
select * from T;
select * from @TV;
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语句,您将保证以与复制记录的PrimaryKey字段相同的顺序生成新的\u ID号。现在,您可以通过按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
将数据加载到具有标识列的表中的INSERT语句保证以与SELECT中order BY子句相同的顺序生成值
如果希望以顺序方式指定标识值
在ORDERBY子句中的排序之后,创建一个
包含具有IDENTITY属性的列,然后运行INSERT。。
选择…按查询排序以填充此表
发件人:
您可以使用此事实将旧标识值与新标识值相匹配。首先收集要复制到临时表中的主键列表。如果需要,还可以包括修改的列值:
select
PrimaryKey,
Col1
--Col2... etc
into #NewRecords
from Table
--where whatever...
然后使用OUTPUT子句执行INSERT,以将新ID捕获到表变量中:
select * from T;
select * from @TV;
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语句,您将保证以与复制记录的PrimaryKey字段相同的顺序生成新的\u ID号。现在,您可以通过按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
不能同时插入父键和子键。必须首先插入父键。如果我理解正确,您是说我不能在主记录的同时插入关系。我不想马上把它们插入关系。我的意思是将我要从中复制的记录的主键插入@TableVariable,插入到与我要复制到的主键相同的记录中。我假设存在输出,并插入这是针对SQL Server的,并基于此给出了答案。不过,最好不要猜测——你能给你的问题添加一个合适的标签吗?sql本身就是一个关于sql语言的标签——由许多不同的RDBMS产品以不同的方式实现ways@Damien_The_Unbeliever谢谢你的提问提示。当有人注意到我是新手并指出如何获得更好的结果时,它会很有帮助。我已将其添加为特定标记。不能同时插入父键和子键
时间必须首先插入父键。如果我理解正确,您是说我不能在主记录的同时插入关系。我不想马上把它们插入关系。我的意思是将我要从中复制的记录的主键插入@TableVariable,插入到与我要复制到的主键相同的记录中。我假设存在输出,并插入这是针对SQL Server的,并基于此给出了答案。不过,最好不要猜测——你能给你的问题添加一个合适的标签吗?sql本身就是一个关于sql语言的标签——由许多不同的RDBMS产品以不同的方式实现ways@Damien_The_Unbeliever谢谢你的提问提示。当有人注意到我是新来的,并指出如何获得更好的结果时,它会很有帮助。我已经将它添加为一个特定的标签。感谢您的帮助。根据你的建议,我补充说我正在使用SQLServer2005来解决这个问题,而合并并不是在2005年实现的。那么,我们就走运了。一般来说,您可以使用非标识列的任何组合来唯一标识行,但由于您要复制所有非标识列,因此不可能存在任何组合。看来是时候用光标了。该死的。好的,谢谢你的帮助,无论是试图找到答案还是提出更好的问题。因为SQL 2005没有指定,这应该被标记为答案。你已经得到了500美元的悬赏@Damien_The_Unsiever,这对我帮助很大。谢谢你的帮助。根据你的建议,我补充说我正在使用SQLServer2005来解决这个问题,而合并并不是在2005年实现的。那么,我们就走运了。一般来说,您可以使用非标识列的任何组合来唯一标识行,但由于您要复制所有非标识列,因此不可能存在任何组合。看来是时候用光标了。该死的。非常感谢您的帮助,无论是试图找到答案还是提出更好的问题。由于未指定SQL 2005,因此应将其标记为答案。您已经获得了500美元的悬赏@Damien_The_Unsiever,这对我帮助很大。