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

如果不存在Oracle,则插入

  •  50
  • cwallenpoole  · 技术社区  · 16 年前

    INSERT ALL
        IF NOT EXISTS( SELECT 1 WHERE fo.primary_key='bar' )
        (
            INSERT INTO 
                schema.myFoo fo ( primary_key, value1, value2 )
            VALUES
                ('bar','baz','bat')
        ),
        
        IF NOT EXISTS( SELECT 1 WHERE fo.primary_key='bar1' )
        (
            INSERT INTO 
                schema.myFoo fo ( primary_key, value1, value2 )
            VALUES
                ('bar1','baz1','bat1')
        )
    SELECT * FROM schema.myFoo;
    

    Oracle有可能做到这一点吗?

    10 回复  |  直到 5 年前
        1
  •  37
  •   Michael Deardeuff    14 年前

    对于oracle 11.2.0.1,有一个 这可以做到:

    insert /*+ IGNORE_ROW_ON_DUPKEY_INDEX(customer_orders,pk_customer_orders) */
      into customer_orders
           (order_id, customer, product)
    values (    1234,     9876,  'K598')
         ;
    

    better approaches

    第一种方法——直接翻译上述语义提示:

    begin
      insert into customer_orders
             (order_id, customer, product)
      values (    1234,     9876,  'K698')
      ;
      commit;
    exception
      when DUP_VAL_ON_INDEX
      then ROLLBACK;
    end;
    

    当存在大量争议时,速度比上述两个提示都快:

    begin
        select count (*)
        into   l_is_matching_row
        from   customer_orders
        where  order_id = 1234
        ;
    
        if (l_is_matching_row = 0)
        then
          insert into customer_orders
                 (order_id, customer, product)
          values (    1234,     9876,  'K698')
          ;
          commit;
        end if;
    exception
      when DUP_VAL_ON_INDEX
      then ROLLBACK;
    end;
    
        2
  •  30
  •   erikkallen    16 年前

    ses1:

    create table t1 (pk int primary key, i int);
    create table t11 (pk int primary key, i int);
    insert into t1 values(1, 1);
    insert into t11 values(2, 21);
    insert into t11 values(3, 31);
    commit;
    

    ses2: insert into t1 values(2, 2);

    ses1:

    MERGE INTO t1 d
    USING t11 s ON (d.pk = s.pk)
    WHEN NOT MATCHED THEN INSERT (d.pk, d.i) VALUES (s.pk, s.i);
    

    ses2: commit;

    ses1: ORA-00001

        3
  •  23
  •   Koen Raymond Chiu    4 年前

    我们可以把 DUAL NOT EXISTS

    INSERT INTO schema.myFoo ( 
        primary_key, value1, value2
    ) 
    SELECT
        'bar', 'baz', 'bat' 
    FROM DUAL
    WHERE NOT EXISTS (
        SELECT 1 
        FROM schema.myFoo
        WHERE primary_key = 'bar'
    );
    
        4
  •  18
  •   Kirk Woll    15 年前

    这仅在要插入的项目不存在时插入。

    if not exists (...) insert ... 
    

    在T-SQL中

    insert into destination (DESTINATIONABBREV) 
      select 'xyz' from dual 
      left outer join destination d on d.destinationabbrev = 'xyz' 
      where d.destinationid is null;
    

        5
  •  15
  •   Nikita    9 年前

    如果您不想从其他表合并,而是插入新数据。..我想出了这个。也许有更好的方法吗?

    MERGE INTO TABLE1 a
        USING DUAL
        ON (a.C1_pk= 6)
    WHEN NOT MATCHED THEN
        INSERT(C1_pk, C2,C3,C4)
        VALUES (6, 1,0,1);
    
        6
  •  5
  •   mmmmmm    16 年前

    然后

    insert myFoo
      select *
         from t
           where t.primary_key not in ( select primary_key from myFoo) 
    

    如果插入的新数据很少,这不是最好的,因为您已经通过线路复制了所有数据。

        7
  •  4
  •   askmish    13 年前
    DECLARE
       tmp NUMBER(3,1);
    BEGIN
      SELECT COUNT(content_id) INTO tmp FROM contents WHERE (condition);
      if tmp != 0 then
        INSERT INTO contents VALUES (...);
      else
        INSERT INTO contents VALUES (...);
      end if;
    END;
    

    我使用了上面的代码。它很长,但很简单,对我来说很有用。类似于迈克尔的代码。

        8
  •  1
  •   zetzer    12 年前

    如果你的表与其他表“独立”(我的意思是,它不会触发级联删除,也不会将任何外键关系设置为null),一个很好的技巧可能是先删除行,然后再插入。它可能是这样的:

    从MyTable中删除prop1='aa';//假设它最多只选择一行!

    如果你删除了不存在的东西,什么都不会发生。

        9
  •  0
  •   Marius Burz    16 年前

    这是对erikkallen发表的评论的回答:

    你不需要临时工作台。如果你 只有几行,(从中选择1行 双UNION SELECT 2 FROM dual)将 更新索引键上的锁,而不是 继续,直到Sess1满足以下任一条件

    好吧,你自己试试,告诉我你是否会遇到同样的错误:

    ses1:

    create table t1 (pk int primary key, i int);
    create table t11 (pk int primary key, i int);
    insert into t1 values(1, 1);
    insert into t11 values(2, 21);
    insert into t11 values(3, 31);
    commit;
    

    ses2: insert into t1 values(2, 2);

    ses1:

    MERGE INTO t1 d
    USING t11 s ON (d.pk = s.pk)
    WHEN NOT MATCHED THEN INSERT (d.pk, d.i) VALUES (s.pk, s.i);
    

    ses2: commit;

    ses1: ORA-00001

        10
  •  0
  •   RaZieRSarE    10 年前

    INSERT INTO schema.myFoo ( primary_key        , value1          , value2         )
                             SELECT 'bar1' AS primary_key ,'baz1' AS value1 ,'bat1' AS value2 FROM DUAL WHERE (SELECT 1 AS value FROM schema.myFoo WHERE LOWER(primary_key) ='bar1' AND ROWNUM=1) is null;