代码之家  ›  专栏  ›  技术社区  ›  rouble

忽略违反重复键索引的行的插入

  •  6
  • rouble  · 技术社区  · 14 年前

    我插入如下:

    INSERT INTO foo (a,b,c)
       SELECT x,y,z
       FROM fubar
       WHERE ...
    

    有问题的数据库是informix11.5。目前所发生的一切就是DB抛出了一个异常。如果我尝试用以下方法处理异常:

    ON EXCEPTION IN (-239)
    END EXCEPTION WITH RESUME;
    

    ... 它没有帮助,因为在捕获异常之后,将跳过整个插入。

    我不认为informix支持INSERT-IGNORE或INSERT。。。重复键…,但如果我错了,请随时纠正我。

    5 回复  |  直到 14 年前
        1
  •  5
  •   BenMorel Sonaten    11 年前

    INSERT INTO foo (a,b,c) 
    SELECT x,y,z 
    FROM fubar 
    WHERE (NOT EXISTS(SELECT a FROM foo WHERE ...))
    
        2
  •  3
  •   Jonathan Leffler    14 年前

    根据是否要了解所有错误(通常是由于数据加载操作导致的),请考虑使用 violations tables .

    START VIOLATIONS TABLE FOR foo;
    

    这将创建一对表foo_vio和foo_dia,以包含有关违反表上完整性约束的行的信息。

    当你吃饱了,你就用:

    STOP VIOLATIONS TABLE FOR foo;
    

    你可以在空闲时清理诊断表。命令上有铃铛和口哨来控制使用哪个表,等等(我应该注意,这假设您使用的是IDS(ibminformixdynamicserver),而不是informixse或informixonline)

    违规表是一个重载选项-适用于负载等。它们通常不用于保护普通SQL。为此,受保护的INSERT(包括SELECT和WHERE NOT EXISTS)相当有效—它要求数据已经存在于表中,但是temp表很容易创建。

        3
  •  3
  •   Jonathan Leffler    7 年前

    还有一些其他的选择要考虑。

    MERGE 声明。这可用于从fubar插入foo中不存在对应行的行,并使用fubar中已存在foo中对应行的值更新foo中的行(重复键问题)。

    另一种看法是:

    SELECT fubar.*
       FROM fubar JOIN foo ON fubar.pk = foo.pk
       INTO TEMP duplicate_entries;
    
    DELETE FROM fubar WHERE pk IN (SELECT pk FROM duplicate_entries);
    
    INSERT INTO foo SELECT * FROM fubar;
    
    ...processs duplicate_entries
    
    DROP TABLE duplicate_entries
    

    这将在尝试插入数据之前清除源表(fubar)中的重复项(假设只有主键是重复的)。duplicate\u entries表包含fubar中具有重复键的行,这些键需要以某种形状或形式进行特殊处理。或者你可以简单地删除并忽略这些行,尽管以我的经验,这很少是个好主意。

        4
  •  2
  •   alaniane    7 年前

    INSERT INTO FOO(Name, Address, Age, Gadget, Price)
    select Name, Age, Gadget, Price
    from foobar
    group by Name, Age, Gadget, Price
    

    另一种可能性是将重复的行写入一个没有索引的错误表,然后在将它们插入新表之前解析重复的行。只需在上面添加having count(*)>1子句。

        5
  •  0
  •   Randy Minder    14 年前

    我不知道Informix,但是使用sqlserver,您可以创建一个索引,使其唯一,然后设置一个属性,使其忽略重复键,这样就不会在重复项上引发错误。只是被忽略了。也许Informix也有相似之处。