2015-10-19 70 views
0

如何克隆一個帶有guid的表以及引用這些guid作爲外鍵的另一個表。克隆表及其外鍵

這兩個表具有一對多的關係。我需要以自動的方式做到這一點。

我的問題是能夠在克隆過程中創建新創建的GUID時引用兩個表之間的關係。

編輯:我需要將條目克隆到表本身,而不是新表。

+0

你有問題到底是什麼?不確定你的RDBM,但在SQL服務器中,你可以簡單地用關係來編寫你的對象,做一個大容量拷貝,數據導入嚮導,編寫對象和數據的腳本等 – Kritner

+0

@Kritner我並不是試圖複製表本身,而是複製表中的條目以獲取測試數據。 – useruseruser

+0

這是什麼關係型數據庫?如果您使用SQL Server使用SQL Server – Kritner

回答

1

基本上,我們希望用新的ID複製表格,但保持與原件相同的關係。 如果需要,你可以保持相同的ID,但實際上這不應該是一個要求;爲了測試,Ids應該不重要 - 只有關係。

我會用兩個表說明這一點:

首先是AnimalType與ID(唯一標識符 - ROWGUID,主鍵)和AnimalType(NVARCHAR)列

二是動物與AnimalName(爲nvarchar)和AnimalType(唯一標識符,外鍵)列

父/查找表:

創建一個新表(newTable)以填充現有表(oldTable)的數據。

有自己的主鍵Id列(ROWGUID,身份等),其默認創建newtable的

創建newtable的一個額外的列來保存oldTable的ID列的值複製

的ID列在newtable中會產生對創造的記錄

唯一ID

第二(子)表:

創建一個新的表(newChildTable)與填充現有表(oldChildTable)的數據。

有自己的外鍵列指向newtable中的主鍵列

創建newChildTable一個額外的列來保存oldChildTable的外鍵列的值複製

一旦創建創建newChildTable,我們填充新parent/lookup Table與原始表格中的數據進行比較,將Id值放入爲此數據添加的額外列中。表格自己的ID將像往常一樣獨特生成。

接下來,我們使用原始表中的數據填充子表,將原始外鍵列值放入添加的此列數據列中。

接下來,我們加入保留原始Id值的列上的兩個新表,並將外鍵列值更新爲父/查找表中的新ID。

最後,我們可以刪除拿着原來的ID值的列,我們只剩下鏈接到同一數據的兩個表,但通過在記錄被複制創建時,我們產生了新的ID。

你不會有原來的IDS任何參考 - 只需在您的測試在任何時候選擇了錯誤的表的情況下(雖然這應該在不同的服務器來完成...)。如果您還需要原始Ids,則可以執行上述操作,不要移動Ids,重命名列等 - 如您所願。

/* 
Create copy of parent/lookup Table with its own Id column 
Add a column to hold the original Ids 
*/ 
CREATE TABLE [dbo].[AnimalTypeBak](
    [Id] [uniqueidentifier] ROWGUIDCOL NOT NULL CONSTRAINT [DF_AnimalTypeBak_Id] DEFAULT (newid()), 
    [OriginalId] [uniqueidentifier] NOT NULL, 
    [AnimalType] [nvarchar](32) NOT NULL, 
CONSTRAINT [PK_AnimalTypeBak] PRIMARY KEY CLUSTERED 
(
    [Id] ASC 
) 
) ON [PRIMARY] 
GO 

/* 
Create copy of child Table 
Add a column to hold the original Foreign Key values 
*/ 
CREATE TABLE [dbo].[AnimalBak](
    [AnimalName] [nvarchar](20) NOT NULL, 
    [OriginalAnimalType] [uniqueidentifier] NOT NULL, 
    [AnimalType] [uniqueidentifier] NOT NULL 
) ON [PRIMARY] 

GO 

/* 
Import data from the parent/lookup Table placing the origional Ids into the added Column 
*/ 
INSERT INTO [dbo].[AnimalTypeBak] 
      ([OriginalId] 
      ,[AnimalType]) 
      SELECT [Id], [AnimalType] 
      FROM [dbo].[AnimalType] 
GO 

/* 
Import data from the child Table placing the origional Foreign Key values into the added Column 
*/ 
INSERT INTO [dbo].[AnimalBak] 
      ([OriginalAnimalType] 
      ,[AnimalName]) 
      SELECT [AnimalType], [AnimalName] 
      FROM [dbo].[Animal] 
GO 

/* 
Update the child Table placing the new parent/lookup Ids into the Foreign Key Column 
*/ 
UPDATE [dbo].[AnimalBak] 
    SET [dbo].[AnimalBak].[AnimalType] = [dbo].[AnimalTypeBak].[Id] 
    FROM [dbo].[AnimalBak] 
    INNER JOIN [dbo].[AnimalTypeBak] 
    ON [dbo].[AnimalBak].[OriginalAnimalType] = [dbo].[AnimalTypeBak].[OriginalId] 
GO 

/* 
Drop the redundant Columns 
*/ 
ALTER TABLE [dbo].[AnimalBak] 
    DROP COLUMN [OriginalAnimalType] 
GO 

ALTER TABLE [dbo].[AnimalTypeBak] 
    DROP COLUMN [OriginalId] 

/* 
Add the Foreign Key Contraint between the two Tables 
*/ 
ALTER TABLE [dbo].[AnimalBak] WITH CHECK ADD CONSTRAINT [FK_AnimalBak_AnimalTypeBak] FOREIGN KEY([AnimalType]) 
REFERENCES [dbo].[AnimalTypeBak] ([Id]) 
GO 

/* 
And select the data to ensure the data is related as it was in the original Tables 
*/ 
SELECT a.AnimalName, a.AnimalType, b.AnimalType FROM [dbo].[AnimalBak] as a INNER JOIN [dbo].[AnimalTypeBak] as b ON b.Id = a.AnimalType 
0
declare @Parents table (Id uniqueidentifier, Name varchar(50)); 
declare @Children table (Id uniqueidentifier, ParentId uniqueidentifier, Name varchar(50)); 

declare @NewId uniqueidentifier = newid(); 

insert into @Parents values (@NewId, 'Original parent'); 
insert into @Children values (newid(), @NewId, 'First original child'); 
insert into @Children values (newid(), @NewId, 'Second original child'); 


declare @Ids table (CloneId uniqueidentifier, OriginalId uniqueidentifier); 


merge @Parents as target 
    using (
     select 
      CloneId = newid(), 
      OriginalId = Id, 
      Name = Name + ' (Cloned)' 
     from 
      @Parents 
     where 
      Id = @NewId 
    ) 
    as source on source.CloneId = target.Id 

when not matched by target then 
    insert (Id, Name) 
    values (source.CloneId, source.Name) 

output 
    source.CloneId, source.OriginalId 
    into @Ids (CloneId, OriginalId); 



merge @Children as target 
    using (
     select 
      Id = newid(), 
      ParentId = ids.CloneId, 
      Name = Name + ' (Cloned)' 
     from 
      @Children c 
      inner join @Ids ids on ids.OriginalId = c.ParentId 
    ) 
    as source on source.Id = target.Id 

when not matched by target then 
    insert (Id, ParentId, Name) 
    values (source.Id, source.ParentId, source.Name); 



select * from @Parents 

select * from @Children