我以前从来没有在 StackOverflow 上发布过问题,因为我总是可以通过搜索在这里找到答案。只是这一次,我想我有一个真正的笨蛋......
我正在编写代码来自动化将数据从一个 SQL Server 数据库移动到另一个数据库的过程。我有一些非常标准的 SQL Server 数据库,它们的一些表之间具有外键关系。直截了当的东西。我的要求之一是需要一举复制整个表,而不是遍历行或使用游标。另一个要求是我必须在 SQL 中执行此操作,没有 SSIS 或其他外部助手。
例如:
INSERT INTO TargetDatabase.dbo.MasterTable
SELECT * FROM SourceDatabase.dbo.MasterTable
这很容易。然后,一旦移动了 MasterTable 中的数据,我就会移动子表的数据。
INSERT INTO TargetDatabase.dbo.ChildTable
SELECT * FROM SourceDatabase.dbo.ChildTable
当然,实际上我使用更明确的 SQL……就像我专门命名所有字段和类似的东西,但这只是一个简化版本。无论如何,到目前为止一切都很好,除了......
问题是主表的主键被定义为一个身份字段。因此,当我插入 MasterTable 时,新表的主键由数据库计算。因此,为了解决这个问题,我尝试使用 OUTPUT INTO 语句将更新的值放入 Temp 表中:
INSERT INTO TargetDatabase.dbo.MasterTable
OUPUT INSERTED.* INTO @MyTempTable
SELECT * FROM SourceDatabase.dbo.MasterTable
所以这就是一切崩溃的地方。由于数据库更改了主键,我到底如何确定临时表中的哪条记录与源表中的原始记录匹配?
你看到问题了吗?我知道新 ID 是什么,只是不知道如何可靠地将它与原始记录匹配。SQL 服务器允许我输出 INSERTED 值,但不允许我在 INSERTED 值旁边输出 FROM TABLE 值。我用触发器试过了,我用SP试过了,总是有同样的问题。
如果我一次只更新一条记录,我可以轻松地将我的 INSERTED 值与我试图插入的原始记录匹配以查看旧主键值和新主键值,但我有这个要求批量执行。
有任何想法吗?
PS:我不允许更改目标或源表的表结构。