我正在尝试开发一种解决方案,使用C#中的SqlBulkCopy将数据从几个客户端数据库自动迁移到相同结构的中央数据库。它抛出了一个"违反唯一键约束"的异常,因为有些表有带有一些唯一值的唯一键列(我完全理解)。
因此,我现在面临的主要挑战是让程序跳过来自源数据库(客户端数据库)的记录,该数据库在目标数据库(中央数据库)上有一个重复的唯一密钥,在目标数据库上获得相应的主键值数据库(中央数据库),并在所有表(在客户端数据库中)上覆盖作为外键存在的跳过记录的主键值。
这是我在软件开发经验中遇到的最大挑战。对于任何能帮助我摆脱困境的人,我将永远感激你。
谢谢。
SqlBulkCopy适合将数据从A批量复制到B,但它不能进行潜在的复杂重键操作。如果你想使用SqlBulkCopy类,那么我会把作业分成两部分;首先,通过确保没有重复密钥(中央数据库中密钥的副本)来准备客户端数据库,然后使用SqlBulkCopy传输数据。
为了找出哪些表具有唯一的索引或约束,可以使用此查询;
select distinct quotename(object_schema_name(i.object_id)) + N'.' + quotename(t.name) as table_name
from sys.indexes i
join sys.tables t on t.object_id = i.object_id
where i.is_unique = 1
order by 1
有多种方法可以确保客户端数据库没有重复密钥。有些想法是;
- 向所有密钥添加客户端标识符。例如,在第一个客户端数据库中的所有键前面加上"A",在第二个客户端数据库的所有键后面加上"B"等。这种方法的缺点是,从数字键到字母数字键通常需要一些努力
- 对每个客户端数据库中的所有键使用定义的数字范围。例如,第一客户端数据库中的所有密钥都从零开始,第二客户端数据库中所有密钥都在1000000开始,第三客户端数据库中全部密钥都在2000000开始等等。这种方法的缺点是,如果一个客户端数据库在一个序列中需要超过分配范围的密钥,则存在范围重叠的风险
- 对所有客户端数据库中的密钥使用uniqueidentifiers。这种方法的缺点是uniqueidentifiers的潜在性能问题以及它们对人类不友好的外观
不幸的是,我想不出一个简单的方法来做你想做的事。