在SqlBulkCopy执行中违反UNIQUE KEY约束

时间:2015-02-12 12:01:41

标签: c# .net sql-server database

我正在尝试开发一种解决方案,使用C#中的SqlBulkCopy自动将数据从多个客户端数据库迁移到相同结构的中央数据库。它抛出了“违反唯一键约束”的例外,因为有些表具有唯一的键列,其中包含一些唯一值(我完全理解)。

所以我现在的主要挑战是以某种方式让程序跳过来自源数据库(客户端数据库)的记录,该数据库在目标数据库(中央数据库)上具有重复的唯一键,在目标上获取相应的主键值 数据库(中央数据库)并覆盖所有表(在客户端数据库中)作为外键存在的跳过记录的主键值。

这是我在软件开发过程中遇到的最大挑战。对于那些可以帮助我摆脱困境的人,我将永远为你负债。

感谢。

1 个答案:

答案 0 :(得分:0)

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'这种方法的缺点是,通常需要一些努力才能从数字键移动到字母数字键。
  • 为每个客户端数据库中的所有键使用已定义的数字范围。例如,第一个客户端数据库中的所有密钥都从零开始,第二个客户端数据库中的所有密钥都从1,000,000开始,第三个客户端数据库中的所有密钥都从2,000,000开始等。这种方法的缺点是重叠的风险如果一个客户端数据库在一个序列中需要的值超过分配的范围值,则会触发范围。
  • 对所有客户端数据库中的密钥使用uniqueidentifier。这种方法的缺点是独特标识符的潜在性能问题以及它们对人类不友好的外观。

不幸的是,我无法想出一个简单的方法来做你想做的事。