Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/77.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在SQL中创建副本时,是否可以将旧密钥链接到新密钥?_Sql_Sql Server_Primary Key_Output - Fatal编程技术网

在SQL中创建副本时,是否可以将旧密钥链接到新密钥?

在SQL中创建副本时,是否可以将旧密钥链接到新密钥?,sql,sql-server,primary-key,output,Sql,Sql Server,Primary Key,Output,我正在尝试复制表中的一条记录,并使用SQLServer2005中的存储过程更改一些值。这很简单,但我还需要使用新的主键复制其他表中的关系。由于此过程用于批量复制记录,我发现很难存储旧密钥和新密钥之间的某些关系。 现在,我正在使用OUTPUT-INTO从批插入中获取新密钥。 例: 有没有这样的方法可以在插入新钥匙的同时轻松地插入旧钥匙,以确保正确的对应钥匙配对 我知道游标是一种选择,但我从未使用过它们,只听到它们以恐怖故事的方式被引用。我更喜欢使用输出到或类似的东西。如果需要跟踪临时表中的新旧键,

我正在尝试复制表中的一条记录,并使用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,这对我帮助很大。