복붙노트

[SQL] 하지 오라클을 존재하는 경우 삽입

SQL

하지 오라클을 존재하는 경우 삽입

나는 행의 수를 삽입하는가는 오라클 쿼리를 실행 할 수 있어야하지만, 기본 키가 존재하고 않는 경우, 그것은 그 삽입을 건너 경우도 확인합니다. 뭔가 같은 :

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;

모든 객실은 오라클과 수 있습니까?

보너스 포인트를 어떻게 PostgreSQL을하거나 MySQL의에서이 작업을 수행하는 말해 줄 수 있다면.

해결법

  1. ==============================

    1.문은 MERGE이라고합니다. 그것을 봐, 내가 너무 게으른 해요.

    문은 MERGE이라고합니다. 그것을 봐, 내가 너무 게으른 해요.

    병합 효과 다음 (감사, 마리우스)을 일으킬 수있는, 원자 아니라고하지만,주의 :

    SESS1 :

    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;
    

    SESS2 : T1 값 (2,2)으로 삽입;

    SESS1 :

    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);
    

    SESS2는 : 커밋

    SESS1 : ORA-00001

  2. ==============================

    2.파티에 늦게오고,하지만 ...

    파티에 늦게오고,하지만 ...

    오라클 11.2.0.1로이 작업을 수행 할 수있는 의미 힌트가있다 : IGNORE_ROW_ON_DUPKEY_INDEX

    예:

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

    업데이트 : 비록이 힌트 작업 (당신이 그것을 정확하게 철자 경우), 오라클 11R2을 필요로하지 않는 더 나은 방법이있다 :

    의미 힌트 위의 첫 번째 방법 - 직접 번역 :

    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;
    
  3. ==============================

    3.삽입 할 항목이 존재하지 않는 경우에만 삽입합니다.

    삽입 할 항목이 존재하지 않는 경우에만 삽입합니다.

    같은 작품 :

    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;
    

    꽤 수 있지만 그것은 간단 하군요하지 않을 수 있습니다 :)

  4. ==============================

    4.우리는 DUAL을 결합하지 귀하의 요구 사항을 보관하기 위해 존재 할 수 있습니다 :

    우리는 DUAL을 결합하지 귀하의 요구 사항을 보관하기 위해 존재 할 수 있습니다 :

    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'
    );
    
  5. ==============================

    5.당신은 다른 테이블에서, 오히려 새로운 데이터 삽입에 병합하지 않으려면 ... 나는이 함께했다. 이 작업을 수행 할 수있는 더 좋은 방법은 아마도 있습니까?

    당신은 다른 테이블에서, 오히려 새로운 데이터 삽입에 병합하지 않으려면 ... 나는이 함께했다. 이 작업을 수행 할 수있는 더 좋은 방법은 아마도 있습니까?

    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. ==============================

    6.그래서를 제거하기 위해이 코드가 클라이언트에 있는지 당신은 서버에 많은 여행을해야합니다.

    그래서를 제거하기 위해이 코드가 클라이언트에 있는지 당신은 서버에 많은 여행을해야합니다.

    모든 삽입 임시 테이블에 데이터를 myFoo와 같은 구조로 IT를 말한다

    그때

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

    이뿐만 아니라 다른 데이터베이스에 작동합니다 - 나는베이스에 이런 짓을했는지

    그것은 당신이 와이어를 통해 모든 데이터를 복사 한 것처럼 새로운 데이터의 거의 삽입 할 경우 최고 없습니다.

  7. ==============================

    7.

    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. ==============================

    8.이 erikkallen에 의해 게시 된 의견에 대한 답변입니다 :

    이 erikkallen에 의해 게시 된 의견에 대한 답변입니다 :

    글쎄, 그것을 자신을 시도하고 같은 오류 여부 말해 :

    SESS1 :

    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;
    

    SESS2 : T1 값 (2,2)으로 삽입;

    SESS1 :

    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);
    

    SESS2는 : 커밋

    SESS1 : ORA-00001

  9. ==============================

    9.테이블이 다른 사람들로부터 "독립"인 경우 (내 말은, 그것은 캐스케이드 삭제하거나 널 (null)에 대한 외래 키 관계를 설정하지 않습니다 실행되지 않습니다), 멋진 트릭 먼저 행을 삭제 한 다음 다시 삽입 할 수 있습니다. 그것은 다음과 같이 갈 수 :

    테이블이 다른 사람들로부터 "독립"인 경우 (내 말은, 그것은 캐스케이드 삭제하거나 널 (null)에 대한 외래 키 관계를 설정하지 않습니다 실행되지 않습니다), 멋진 트릭 먼저 행을 삭제 한 다음 다시 삽입 할 수 있습니다. 그것은 다음과 같이 갈 수 :

    을 MyTable 어디에서 삭제 prop1 = 'AAA'; //이 최대 하나 개의 행을 선택한다고 가정!

    INSERT INTO을 MyTable (prop1, ...) 값 ( 'AAA', ...);

    당신이 존재하지 않는 무언가를 삭제하는 경우는 아무것도 일어나지 않습니다.

  10. ==============================

    10.INSERT INTO schema.myFoo (primary_key와, 값 1, 값) 널 (LOWER (primary_key와는) = 'BAR1가'AND ROWNUM = 1 schema.myFoo FROM 값으로 1을 선택) FROM DUAL 값 2 AS primary_key와 AS SELECT 'BAR1', 'baz1'AS VALUE1 'BAT1를';

    INSERT INTO schema.myFoo (primary_key와, 값 1, 값) 널 (LOWER (primary_key와는) = 'BAR1가'AND ROWNUM = 1 schema.myFoo FROM 값으로 1을 선택) FROM DUAL 값 2 AS primary_key와 AS SELECT 'BAR1', 'baz1'AS VALUE1 'BAT1를';

  11. from https://stackoverflow.com/questions/1702832/insert-if-not-exists-oracle by cc-by-sa and MIT license