寻找一种方法将 table 数据从一个 SQL 服务器数据库复制到另一个(关于身份和外键)
Searching for a way to copy table data from one SQL Server database to another (concerning Identity and Foreign Keys)
初题(后面有答案):
我面临以下挑战:我有一个 Oracle 数据库,其中一个软件 (Infor Supplier Exchange) 曾经创建 tables 并用数据填充它们。此数据库应迁移到 SQL 服务器,然后应使用迁移的数据执行 Infor 软件升级。
我的一位同事已经使用 Microsoft 的脚本将 Oracle 数据库迁移到现在可供我使用的 SQL 服务器。即使设置了“保持标识”标志,新数据库中的主键也没有设置其标识(自动增量)——但 Infor 软件稍后需要添加数据。
我找到了一种通过 SSMS 更改每个相关数据库的身份(及其种子)的方法 table:右键单击 table,设计,更改“身份规范” “手动。但我有超过 300 tables:这项工作将花费数小时(和理智)。
我还发现我可以使用 SSMS 的“导出数据”任务。您必须知道,Infor 软件提供了一个数据库安装程序,它使用 EMPTY 数据库创建所有必需的 tables、密钥、身份属性等。所以我基本上可以将数据从“Oracle 迁移的旧数据库”导出到“Infor 准备的新数据库”,因为它们(应该)具有相同的 table 名称、键等 - 除了身份 属性和用户数据。
在导出数据任务中可以勾选“启用标识插入”。问题在于,此 SSMS 功能在处理带有外键的 table 时中止,而引用的 table 尚不存在。所以我可以再次检查旧数据库,首先对所有没有主键的 tables 执行“复制数据”任务,然后尝试剩余的 tables,直到所有数据都复制到新数据库。但这又是一次很大的努力,因为我必须重新处理每个错误或事先检查所有约束。
你有更好的方法吗?是否可以从db A(with 300+ tables)复制数据到db B(with same table structure),希望有工具解决tables的正确顺序因为他们的外键约束?
如果您对此问题有疑问,我可以更详细地解释。提前致谢。
解法:
我通过暂时禁用约束和触发器解决了这个任务。步骤是:
EXEC sp_MSForEachTable "ALTER TABLE ? NOCHECK CONSTRAINT all"
sp_msforeachtable "ALTER TABLE ? DISABLE TRIGGER all"
EXEC sp_MSForEachTable "DELETE FROM ?"
我不得不清除目标数据库的 table,因为它们由 Infor 安装程序填充了一些示例数据。数据导出任务可以附加行或尝试删除现有行(具有相同的主键)。但这在内部使用了 TRUNCATE,它不适用于外键约束,即使它们被上述命令禁用。
下一步:执行SSMS数据库任务“导出数据”。忽略数据类型转换错误(某些类型不同于 Oracle-Migration 到目标 SQL 模式,例如 varchar 到 nvarchar,我检查并判断为不重要)。
exec sp_MSForEachTable "ALTER TABLE ? WITH CHECK CHECK CONSTRAINT all"
sp_msforeachtable @command1="print '?'", @command2="ALTER TABLE ? ENABLE TRIGGER all"
使用供应商的 SQL 服务器数据库架构并自己加载数据通常是迁移到带有打包软件的 SQL 服务器的正确方法。但供应商可能会提供其他指导。
与其尝试以与外键约束兼容的顺序加载表(这并不总是可能的),不如在加载数据库之前禁用所有外键并在之后重新启用它们。参见 Temporarily disable all foreign key constraints
初题(后面有答案):
我面临以下挑战:我有一个 Oracle 数据库,其中一个软件 (Infor Supplier Exchange) 曾经创建 tables 并用数据填充它们。此数据库应迁移到 SQL 服务器,然后应使用迁移的数据执行 Infor 软件升级。
我的一位同事已经使用 Microsoft 的脚本将 Oracle 数据库迁移到现在可供我使用的 SQL 服务器。即使设置了“保持标识”标志,新数据库中的主键也没有设置其标识(自动增量)——但 Infor 软件稍后需要添加数据。
我找到了一种通过 SSMS 更改每个相关数据库的身份(及其种子)的方法 table:右键单击 table,设计,更改“身份规范” “手动。但我有超过 300 tables:这项工作将花费数小时(和理智)。
我还发现我可以使用 SSMS 的“导出数据”任务。您必须知道,Infor 软件提供了一个数据库安装程序,它使用 EMPTY 数据库创建所有必需的 tables、密钥、身份属性等。所以我基本上可以将数据从“Oracle 迁移的旧数据库”导出到“Infor 准备的新数据库”,因为它们(应该)具有相同的 table 名称、键等 - 除了身份 属性和用户数据。
在导出数据任务中可以勾选“启用标识插入”。问题在于,此 SSMS 功能在处理带有外键的 table 时中止,而引用的 table 尚不存在。所以我可以再次检查旧数据库,首先对所有没有主键的 tables 执行“复制数据”任务,然后尝试剩余的 tables,直到所有数据都复制到新数据库。但这又是一次很大的努力,因为我必须重新处理每个错误或事先检查所有约束。
你有更好的方法吗?是否可以从db A(with 300+ tables)复制数据到db B(with same table structure),希望有工具解决tables的正确顺序因为他们的外键约束?
如果您对此问题有疑问,我可以更详细地解释。提前致谢。
解法:
我通过暂时禁用约束和触发器解决了这个任务。步骤是:
EXEC sp_MSForEachTable "ALTER TABLE ? NOCHECK CONSTRAINT all"
sp_msforeachtable "ALTER TABLE ? DISABLE TRIGGER all"
EXEC sp_MSForEachTable "DELETE FROM ?"
我不得不清除目标数据库的 table,因为它们由 Infor 安装程序填充了一些示例数据。数据导出任务可以附加行或尝试删除现有行(具有相同的主键)。但这在内部使用了 TRUNCATE,它不适用于外键约束,即使它们被上述命令禁用。
下一步:执行SSMS数据库任务“导出数据”。忽略数据类型转换错误(某些类型不同于 Oracle-Migration 到目标 SQL 模式,例如 varchar 到 nvarchar,我检查并判断为不重要)。
exec sp_MSForEachTable "ALTER TABLE ? WITH CHECK CHECK CONSTRAINT all"
sp_msforeachtable @command1="print '?'", @command2="ALTER TABLE ? ENABLE TRIGGER all"
使用供应商的 SQL 服务器数据库架构并自己加载数据通常是迁移到带有打包软件的 SQL 服务器的正确方法。但供应商可能会提供其他指导。
与其尝试以与外键约束兼容的顺序加载表(这并不总是可能的),不如在加载数据库之前禁用所有外键并在之后重新启用它们。参见 Temporarily disable all foreign key constraints