更新时SQL约束IGNORE_DUP_KEY

时间:2010-08-03 10:52:25

标签: sql sql-server sql-server-2005 updates

我在IGNORE_DUP_KEY的表上有一个约束。这允许批量插入部分工作,其中一些记录是欺骗而一些不是(仅插入非欺骗)。但是,它不允许更新部分工作,我只希望更新这些记录,而不会创建dupes。

有人知道在应用更新时我如何支持IGNORE_DUP_KEY吗?

我正在使用MS SQL 2005

3 个答案:

答案 0 :(得分:1)

如果我理解正确,你想在没有指定必要的WHERE逻辑的情况下进行UPDATE,以避免产生重复?

create table #t (col1 int not null, col2 int not null, primary key (col1, col2))

insert into #t 
select 1, 1 union all 
select 1, 2 union all 
select 2, 3

-- you want to do just this...
update #t set col2 = 1

-- ... but you really need to do this
update #t set col2 = 1
where not exists (
    select * from #t t2
    where #t.col1 = t2.col1 and col2 = 1
    )

想到的主要选项是:

  1. 使用完整的UPDATE语句以避免创建重复项
  2. 使用INSTEAD OF UPDATE触发器“拦截”UPDATE并仅执行不会创建重复的UPDATE
  3. 使用逐行处理技术(如游标)并将每个UPDATE包装在TRY ... CATCH ...或任何语言等效的
  4. 我认为没有人可以告诉你哪一个是最好的,因为这取决于你正在尝试做什么以及你正在做什么环境。但是因为逐行处理可能会产生一些错误积极的,我会尝试坚持基于集合的方法。

答案 1 :(得分:0)

我觉得你应该使用MERGE语句,然后在更新部分你真的不应该更新你想拥有的密钥。这也意味着您必须在表中定义一个键是唯一的(设置唯一索引或定义为主键)。然后任何带有重复键的更新或插入都将失败。

编辑:我认为此链接有助于此:

http://msdn.microsoft.com/en-us/library/bb522522.aspx

答案 2 :(得分:0)

我不确定究竟发生了什么,但是如果您在重量加载过程中插入重复项并更新主键,那么临时表可能就是您的解决方案。您创建一个表,确保在批量加载之前为空,然后使用文件中的100%原始数据加载它,然后将该数据处理到真实表中(基于最佳设置)。您可以执行以下操作来插入尚不存在的所有行:

INSERT INTO RealTable
        (pk, col1, col2, col3)
    SELECT
        pk, col1, col2, col3
        FROM StageTable s
        WHERE NOT EXISTS (SELECT
                              1
                              FROM RealTable r
                              WHERE s.pk=r.pk
                         )

首先防止重复是最好的。您还可以通过加入临时表等在您的真实表上执行UPDATE。这将避免需要“解决”约束。当您解决约束时,通常会很难找到错误。