認為,
我有一張桌子tblClasses和tblStudents
現在每個班級都有多個學生。
tblClass
ID Name
1 ClassA
2 ClassB
3 ClassC
tbl學生
ID Name Class_ID
1. john 1
2. Mathew 1
3. Imran 2
4. Jenny 3
現在,我有有完全一樣的另一臺服務器db和表格,我從資料復制server 1到server 2從相同的表使用Select和Insert如
insert into server2.dbo.tblClass (Name)
select Name from server1.dbo.tblClass
并為 tblStudents
insert into server2.dbo.tblStudents (Name, Class_ID)
select Name, Class_ID from server1.dbo.tblStudents
現在這是確定的,但真正的問題是,在server2復制資料后,如何填充tblStudentsFKClass_ID與實際IDs的tblClass將資料插入之后產生tblStudents的server2,因為的PK身份和自動遞增,不能改變設計。
在這種情況下該怎么辦?
簡而言之,當復制父資料和子資料時,在子表中,外鍵欄位需要填充父的實際 ID,而不是復制它的位置的 ID,這顯然是不同的。
我不允許更改表設計或屬性,并且必須使用查詢進行更改。
有什么建議?
uj5u.com熱心網友回復:
該方法是創建一個ClassId階級的記錄插入映射表,并使用該映射表來轉換OldClassId到NewClassId新的學生表:
declare @ClassIds table (OldClassId int, NewClassId int);
merge into newDB.dbo.tblClasses as target
using
(
select
Id = Id * (-1),
[Name]
from
oldDB.dbo.tblClasses
)
as source on source.Id = target.Id
when not matched by target then
insert ([Name])
values (source.[Name])
output source.Id * (-1), inserted.Id -- ← the trick is here
into @ClassIds (OldClassId, NewClassId);
insert into newDB.dbo.tblStudents
select
s.Id,
s.[Name],
ClassId = ids.NewClassId
from
oldDB.dbo.tblStudents s
inner join @ClassIds ids on ids.OldClassId = s.ClassId;
主要的技巧是該MERGE陳述句不僅可以inserted與deleted列一起使用(如INSERT, UPDATE,DELETE陳述句那樣),而且還可以與source列一起使用。
uj5u.com熱心網友回復:
我能想到的有兩種方法:
首先是使用SET IDENTITY_INSERT tblClass ON. 這不是設計更改,因此您應該能夠做到。之后,您可以在 tblClass.ID 中插入您自己的值(盡管您需要選擇串列括號):
insert tblClass(ID,Name) values (1, 'ClassA')....
或者,您可以進行查詢,將學生 id 連接到 class names,然后使用它來創建相應的連接:
-- export/save this in temp table
select s.Name,c.Name as className
into #a
from tblStudents s
left join tblClass c on s.Class_ID=c.ID
--now use this to fill db2 tblStudents
insert tblStudents(Name,Class_ID)
select #a.Name,c.ID
from
#a
inner join tblClass c on #a.className=c.Name
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/361953.html
標籤:sql sql-server 查询语句 存储过程
