基本上,我们希望复制具有新 ID 的表,但保持与原始表的关系相同。
如果需要,您可以保留相同的 ID,但实际上这不应该是必需的;对于测试,ID 应该无关紧要 - 只有关系。
我将用两个表格来演示:
第一个是AnimalType with Id (uniqueidentifier - RowGuid, Primary Key) and AnimalType (nvarchar) Columns
第二个是 AnimalName (nvarchar) 和 AnimalType (uniqueidentifier, Foreign Key) Columns的Animal
对于父/查找表:
创建一个新表 (newTable) 以填充现有表 (oldTable) 的数据。
使用其默认的主键 ID 列(ROWGUID、IDENTITY 等)创建 newTable
在 newTable 中创建一个额外的 Column 来保存 oldTable 的 Id Column 值的副本
newTable 中的 Id 列将在创建记录时生成唯一的 Id
第二个(子)表:
创建一个新表 (newChildTable) 以填充现有表 (oldChildTable) 的数据。
使用自己的外键列创建 newChildTable 以指向 newTable 的主键列
在 newChildTable 中创建一个额外的 Column 来保存 oldChildTable 的外键列值的副本
创建后,我们使用原始表中的数据填充新的父/查找表,并将 Id 值放置在为该数据添加的额外列中。 Table 自己的 Id 会像往常一样生成唯一的。
接下来,我们用原始表中的数据填充子表,将原始外键列值放入该数据的添加列中。
接下来,我们在保存原始 Id 值的 Columns 上加入两个新表,并将外键列值更新为父/查找表中的新 Id。
最后,我们可以删除保存原始 Id 值的列,剩下的两个表链接到相同的数据,但通过我们在复制记录时创建时生成的新 Id。
您不会对原始 ID 有任何引用 - 以防在测试中的任何时候选择错误的表(尽管这应该在不同的服务器中完成......)。如果您也需要原始 Id,则可以执行上述操作,而不是移动 Id,重命名列等 - 如您所愿。
/*
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