假设我有表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
)
Run Code Online (Sandbox Code Playgroud)
所以,有一个数据集的树结构.每个数据集代表一个计划,可能包含子数据集.每个表中的每一行都有一个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 …Run Code Online (Sandbox Code Playgroud) 注意:我在这里使用.NET 3.5.
假设我有以下构造函数的示例基类/子类:
public Person(string name, int age, string job, bool isMale)
{
Name = name;
Age = age;
Job = job;
IsMale = isMale;
}
public CollegeStudent(string name) : this(name, 18) {}
public CollegeStudent(string name, int age) : this(name, age, "Student") {}
public CollegeStudent(string name, int age, string job) : this(name, age, job, true) {}
public CollegeStudent(string name, int age, string job, bool isMale) : base(name, age, job, isMale) {}
Run Code Online (Sandbox Code Playgroud)
编译器是否足够聪明,可以看到子构造函数正在做的唯一事情是相互链接并最终只调用基本构造函数?那么,它可以只更改"this"构造函数初始值设定项,以便在编译时直接调用基础构造函数?
所以它本质上会改变所有内容:
public CollegeStudent(string name) : base(name, 18, "Student", …Run Code Online (Sandbox Code Playgroud) 这是在SQL Server 2005中.
我有一个地址表:
dbo.Address
(
AddressID INT IDENTITY(1, 1) PRIMARY KEY
LastUpdateBy VARCHAR(30)
<bunch of address columns>
)
Run Code Online (Sandbox Code Playgroud)
我还有一个历史表:
dbo.AddressHistory
(
AddressID INT,
AsOf DATETIME,
UpdateBy VARCHAR(30)
<all the address columns>
CONSTRAINT PK_dbo_AddressHistory PRIMARY KEY CLUSTERED (AddressID, AsOf)
)
Run Code Online (Sandbox Code Playgroud)
我在dbo.Address上有一个触发器,用于在INSERT和UPDATE上创建历史条目,它基本上会这样做:
INSERT INTO dbo.AddressHistory(AddressID, AsOf, UpdateBy, <address columns>)
SELECT AddressID, CURRENT_TIMESTAMP, @UpdateBy, <address columns>
FROM INSERTED
Run Code Online (Sandbox Code Playgroud)
但是,每隔一段时间,我就会在dbo.AddressHistory上获得PK违规,抱怨插入了重复的PK.如果AddressHistory的PK部分是插入的当前时间戳,这怎么可能?
即使执行此操作,也会成功在历史表中插入两行:
INSERT INTO dbo.Address
(LastUpdateBy, <address columns>)
SELECT 'test', <address columns>
FROM dbo.Address
WHERE AddressID < 3
Run Code Online (Sandbox Code Playgroud)
我为dbo.Address表唯一更新的sproc将为给定的AddressID更新一行.所以它应该一次只更新一行.我的插入sproc一次只插入一行.
知道什么条件会导致这种情况发生吗?
我在jQuery文档中注意到,从1.4开始,调用没有args的$()只返回一个空集而不是$(document).http://api.jquery.com/jQuery/#returning-empty-set
那么,$(文件)没有其他简写吗?
我问,因为如果我试图通过变量中的ID来选择元素,我无法决定哪个更丑:$("#"+ myID)或$(document).find(myId).
谢谢.