1

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

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

我正在使用 MS SQL 2005

4

3 回答 3

1

我不确定到底发生了什么,但是如果您在批量加载过程中插入重复项和更新主键,那么临时表可能是您的解决方案。您创建一个在批量加载之前确保为空的表,然后使用文件中的 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
                         )

首先防止重复是最好的。您还可以通过加入临时表等来对真实表进行更新。这将避免“解决”约束的需要。当您绕过这些限制时,通常会产生难以发现的错误。

于 2010-08-03T12:44:12.883 回答
1

如果我理解正确,您想在不指定必要的 WHERE 逻辑以避免创建重复项的情况下进行更新?

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 触发器来“拦截”更新,并且只执行不会创建重复的更新
  3. 使用诸如游标之类的逐行处理技术并将每个 UPDATE 包装在 TRY...CATCH... 或任何语言的等价物

我认为没有人可以告诉你哪个最好,因为这取决于你想要做什么以及你在什么环境中工作。但是因为逐行处理可能会产生一些误报,我会尝试坚持基于集合的方法。

于 2010-08-03T13:15:36.860 回答
0

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

编辑:我认为此链接将对此有所帮助:

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

于 2010-08-03T11:10:05.933 回答