鉴于以下内容(表1):
Id Field1 Field2 ...
-- ------ -------
NULL 1 2
NULL 3 4
...
我想将Field1和Field2的值插入到不同的表中(表2)。 Table2有一个自动增量整数主键。我想从Table2中检索新的PK并更新上面的Id列(表1)。
我意识到这不是传统的 - 它不是我需要经常做的事情,只是一次性的一些迁移工作。我使用INSERT INTO, OUTPUT, INSERTED.Id
做了一些尝试,但失败了。 “循环”到Table1中的PK必须与插入的Field1 / Filed2的值绑定。
答案 0 :(得分:2)
你应该能够进行插入,然后删除并重新插入。
create table t1
( id int, f1 int, f2 int);
create table t2
( id int primary key IDENTITY , f1 int, f2 int);
insert into t1 (id, f1, f2) values (null, 1, 2);
insert into t1 (id, f1, f2) values (null, 3, 4);
insert into t1 (id, f1, f2) values (null, 5, 6);
insert into t1 (id, f1, f2) values (null, 5, 6);
insert into t2 (f1, f2)
select f1, f2 from t1 where id is null;
delete t1
from t1 join t2 on (t1.f1 = t2.f1 and t1.f2 = t2.f2);
insert into t1
select id, f1, f2 from t2;
select * from t1;
请参阅SQLFiddle上的此示例。
答案 1 :(得分:2)
您需要某种类型的唯一键来匹配每个表中的行。我冒昧地为你的每个表添加一个TempGuid列(你可以稍后放弃):
-- Setup test data
declare @Table1 table (
Id int null
, Field1 int not null
, Field2 int not null
, TempGuid uniqueidentifier not null unique
)
insert into @Table1 (Field1, Field2, TempGuid) select 1, 2, newid()
insert into @Table1 (Field1, Field2, TempGuid) select 3, 4, newid()
declare @Table2 table (
Id int not null primary key identity(1, 1)
, Field1 int not null
, Field2 int not null
, TempGuid uniqueidentifier not null unique
)
-- Fill Table2
insert into @Table2 (Field1, Field2, TempGuid)
select Field1, Field2, TempGuid
from @Table1
-- Update Table1 with the identity values from Table2
update a
set a.Id = b.Id
from @Table1 a
join @Table2 b on a.TempGuid = b.TempGuid
-- Show results
select * from @Table1
如果您在Table1上已经插入了一个唯一的键,那么 Output
将是可行的。你也可以在循环或游标中做一个临时的唯一键(可能是GUID)并一次处理一行,但这对我来说似乎更糟。
<强>更新强>
以下是在表上运行的实际SQL:
-- Add TempGuid columns
alter table Table1 add TempGuid uniqueidentifier null
update Table1 set TempGuid = newid()
alter table Table2 add TempGuid uniqueidentifier not null
-- Fill Table2
insert into Table2 (Field1, Field2, TempGuid)
select Field1, Field2, TempGuid
from Table1
-- Update Table1 with the identity values from Table2
update a
set a.Id = b.Id
from Table1 a
join Table2 b on a.TempGuid = b.TempGuid
-- Remove TempGuid columns
alter table Table1 drop column TempGuid
alter table Table2 drop column TempGuid
答案 2 :(得分:1)
假设您可以完全控制架构定义,请将外键添加到引用Table2
主键的Table1
。
执行数据插入:
INSERT INTO Table2 (Field1, Field2, T1PK)
SELECT Field1, Field2, PK FROM Table1
然后回填表1:
UPDATE t1 SET Id = t2.PK
FROM Table1 t1 INNER JOIN Table2 t2 ON t2.T1PK = t1.PK
然后从T1PK
删除额外的列(Table2
)。
编辑:
由于Table1
中没有PK,只需在Table1
中添加一个,然后使用它,然后将其放在最后。
例如......
ALTER TABLE Table1 ADD COLUMN T1PK UNIQUEIDENTIFIER CONSTRAINT Table1_PK PRIMARY KEY DEFAULT NEWID();
ALTER TABLE Table2 ADD COLUMN T1PK UNIQUEIDENTIFIER NULL
INSERT INTO Table2 (Field1, Field2, T1PK)
SELECT Field1, Field2, T1PK FROM Table1
UPDATE t1 SET Id = t2.PK
FROM Table1 t1 INNER JOIN Table2 t2 ON t2.T1PK = t1.T1PK
ALTER TABLE Table1 DROP CONSTRAINT Table1_PK
ALTER TABLE Table1 DROP COLUMN T1PK
ALTER TABLE Table2 DROP COLUMN T1PK
答案 3 :(得分:0)
这不是很好,但应该做一次性的努力。
create table tableA
(
id int,
field1 int,
field2 int
)
create table tableB
(
id int identity(1,1),
field1 int,
field2 int
)
insert into tableA select NULL, 1, 2
insert into tableA select NULL, 2, 3
declare @field1_value int;
declare @field2_value int;
declare @lastInsertedId int;
DECLARE tableA_cursor CURSOR FOR
select field1, field2 from tableA
OPEN tableA_cursor
FETCH NEXT FROM tableA_cursor INTO @field1_value, @field2_value
WHILE @@FETCH_STATUS = 0
BEGIN
insert into tableB select @field1_value, @field2_value
set @lastInsertedId = (SELECT SCOPE_IDENTITY())
update a
set id = @lastInsertedId
from tableA a
where field1 = @field1_value
and field2 = @field2_value
print @field1_value
FETCH NEXT FROM tableA_cursor
INTO @field1_value, @field2_value
END
CLOSE tableA_cursor
DEALLOCATE tableA_cursor
不存在检查:
declare @field1_value int;
declare @field2_value int;
declare @lastInsertedId int;
DECLARE tableA_cursor CURSOR FOR
select field1, field2 from tableA
OPEN tableA_cursor
FETCH NEXT FROM tableA_cursor INTO @field1_value, @field2_value
WHILE @@FETCH_STATUS = 0
BEGIN
IF NOT EXISTS
(
select * from tableB
where field1 = @field1_value
and field2 = @field2_value
)
BEGIN
insert into tableB
select @field1_value, @field2_value
set @lastInsertedId = (SELECT SCOPE_IDENTITY())
update a
set id = @lastInsertedId
from tableA a
where field1 = @field1_value
and field2 = @field2_value
END
FETCH NEXT FROM tableA_cursor
INTO @field1_value, @field2_value
END
CLOSE tableA_cursor
DEALLOCATE tableA_cursor