2010-09-15 117 views
2

我有一個場景,我有一個父表與兩個或三個表具有「1對多」關係。這些子表格與更多表格再次具有「一對多」關係等等。這可以達到5到6級的等級。在tsql中高效複製記錄

現在,基於父表的單個主鍵值,我想要複製數據庫中與其相關的所有信息。我編寫了一個存儲過程,它使用遊標並逐個插入子行,併爲每個插入設置新的外鍵值。但是由於子表中的記錄數量很高,所以它消耗了一些時間。

有沒有其他有效的方法來做到這一點?

回答

2

SQL Server 2008

CREATE TABLE t_parent (id INT NOT NULL PRIMARY KEY IDENTITY, value VARCHAR(100)) 
CREATE TABLE t_child (id INT NOT NULL PRIMARY KEY IDENTITY, parent INT NOT NULL, value VARCHAR(100)) 
CREATE TABLE t_grandchild (id INT NOT NULL PRIMARY KEY IDENTITY, child INT NOT NULL, value VARCHAR(100)) 

INSERT 
INTO t_parent (value) 
VALUES ('Parent 1') 

INSERT 
INTO t_parent (value) 
VALUES ('Parent 2') 

INSERT 
INTO t_child (parent, value) 
VALUES (1, 'Child 2') 

INSERT 
INTO t_child (parent, value) 
VALUES (2, 'Child 2') 

INSERT 
INTO t_grandchild (child, value) 
VALUES (1, 'Grandchild 1') 

INSERT 
INTO t_grandchild (child, value) 
VALUES (1, 'Grandchild 2') 

INSERT 
INTO t_grandchild (child, value) 
VALUES (2, 'Grandchild 3') 

DECLARE @tt TABLE (oid INT, nid INT) 

MERGE 
INTO t_parent 
USING (
     SELECT id, value 
     FROM t_parent 
     ) p 
ON  1 = 0 
WHEN NOT MATCHED THEN 
INSERT (value) 
VALUES (value) 
OUTPUT p.id, INSERTED.id 
INTO @tt; 

MERGE 
INTO t_child 
USING (
     SELECT c.id, p.nid, c.value 
     FROM @tt p 
     JOIN t_child c 
     ON  c.parent = p.oid 
     ) c 
ON  1 = 0 
WHEN NOT MATCHED THEN 
INSERT (parent, value) 
VALUES (nid, value) 
OUTPUT c.id, INSERTED.id 
INTO @tt; 

INSERT 
INTO t_grandchild (child, value) 
SELECT c.nid, gc.value 
FROM @tt c 
JOIN t_grandchild gc 
ON  gc.child = c.oid 

在早期版本的SQL Server,你將不得不做SELECT後跟INSERT找出PRIMARY KEY的新值。

+0

感謝Quassnoi,我正在使用SQL 05.你能否給出在INSERT中使用OUTPUT的例子。我想要新增記錄ID。 – Sami 2010-09-17 06:38:23

1

您必須一次插入一個表,但如果您允許新父項子表中的FK值與原始項的FK值相同,則可以通過插入集而不是行來完成此操作家長。

假設你有一個父表的視圖,並在你的sp中將其限制在要複製的行上(pk = 1,說)。 然後將該行插入到父表中,用PK = 2代替PK val。

現在使用其中一個子表的第二個視圖。在您的sp中,將行集限制爲PK = 1的那些行。再次,將所有這些行插入到同一個子表中,用PK = 2代替PK字段val。