假设我有表 A 和表 B。表 B 引用表 A。我想深复制表 A 和表 B 中的一组行。我希望所有新表 B 行都引用新表 A 行。
请注意,我没有将行复制到任何其他表中。表 A 中的行将复制到表 A 中,表 B 中的行将复制到表 B 中。
如何确保将外键引用作为副本的一部分进行重新调整?
为了澄清,我试图找到一种通用的方法来做到这一点。我给出的示例涉及两个表,但实际上依赖关系图可能要复杂得多。即使是动态生成 SQL 来完成工作的通用方法也可以。
更新:
人们在问为什么这是必要的,所以我将提供一些背景信息。这可能太多了,但这里有:
我正在使用已移至客户端-服务器模型的旧桌面应用程序。但是,该应用程序仍然使用基本的内部二进制文件格式来存储其表的数据。数据文件只是一个标题,后面跟着一系列行,每一行只是二进制序列化的字段值,其顺序由模式文本文件确定。唯一的好处是它非常快。其他方面都很糟糕。我正在将应用程序移动到 SQL Server 并尽量不降低性能。
这是一种调度应用程序;数据对任何人都不重要,也不需要审计跟踪等。这不是海量数据,如果数据库变得太大,我们不一定需要保留非常旧的数据。
他们习惯的一项功能是能够复制整个时间表以创建他们可以处理的“假设”场景。任何用户都可以根据需要多次执行此操作。在旧数据库中,每个计划的数据文件都存储在它们自己的数据文件夹中,按名称标识。因此,复制计划就像复制数据文件夹并重命名一样简单。
我必须能够使用 SQL Server 有效地做同样的事情,否则迁移将无法进行。也许您认为我只能复制实际更改的数据以避免冗余;但老实说,这听起来太复杂了,不可行。
为了将另一个扳手投入其中,可以有一个时间表数据文件夹的层次结构。因此,一个数据文件夹可能包含一个数据文件夹,其中可能包含一个数据文件夹。并且复制可以发生在任何级别。
在 SQL Server 中,我正在实现一个嵌套集层次结构来模仿这一点。我有一个这样的 DATA_SET 表:
CREATE TABLE dbo.DATA_SET
(
DATA_SET_ID UNIQUEIDENTIFIER PRIMARY KEY,
NAME NVARCHAR(128) NOT NULL,
LFT INT NOT NULL,
RGT INT NOT NULL
)
因此,存在数据集的树形结构。每个数据集代表一个时间表,并且可能包含子数据集。每个表中的每一行都有一个 DATA_SET_ID FK 引用,指示它属于哪个数据集。每当我复制数据集时,我都会将表中该数据集的所有行以及所有其他数据集复制到同一个表中,但会引用新的数据集。
因此,这是一个简单的具体示例:
CREATE TABLE FOO
(
FOO_ID BIGINT PRIMARY KEY,
DATA_SET_ID BIGINT FOREIGN KEY REFERENCES DATA_SET(DATA_SET_ID) NOT NULL
)
CREATE TABLE BAR
(
BAR_ID BIGINT PRIMARY KEY,
DATA_SET_ID BIGINT FOREIGN KEY REFERENCES DATA_SET(DATA_SET_ID) NOT NULL,
FOO_ID UNIQUEIDENTIFIER PRIMARY KEY
)
INSERT INTO FOO
SELECT 1, 1 UNION ALL
SELECT 2, 1 UNION ALL
SELECT 3, 1 UNION ALL
INSERT INTO BAR
SELECT 1, 1, 1
SELECT 2, 1, 2
SELECT 3, 1, 3
因此,假设我将数据集 1 复制到 ID 为 2 的新数据集。复制后,表将如下所示:
FOO
FOO_ID, DATA_SET_ID
1 1
2 1
3 1
4 2
5 2
6 2
BAR
BAR_ID, DATA_SET_ID, FOO_ID
1 1 1
2 1 2
3 1 3
4 2 4
5 2 5
6 2 6
如您所见,新的 BAR 行正在引用新的 FOO 行。这不是我要询问的 DATA_SET_ID 的重新布线。我问的是一般重新布线外键。
所以,这肯定是太多的信息,但你去了。
我敢肯定有很多关于像这样批量复制数据的想法的性能问题。桌子不会很大。我不希望任何表中的记录超过 1000 条,而且大多数表会比这小得多。可以直接删除旧数据集而不会产生任何影响。
谢谢,泰德兹