2017-05-09 10 views
3

에 따라 같은 테이블에 MERGE 사용 : 나는 신선한를 삽입해야오라클은 내가 아래 오라클 시퀀스를 생성 한 조건

TASK_ID nextval from TASK_ID_SEQ 
TASK_DATE SYSDATE 
TASK_TYPE <value fed from data> 

: 나는 다음과 같이 데이터베이스 테이블 TASK

CREATE SEQUENCE TASK_ID_SEQ START WITH 1 INCREMENT BY 1 NOCACHE NOCYCLE; 

TASKTASK_TYPE이 의 날짜에 TASK 테이블에 나타나지 않으면 무시하고 그렇지 않으면 무시하십시오.

다음 구문이 정확합니까?

MERGE INTO TASK a 
USING (SELECT b.task_date FROM TASK b) 
ON (a.task_type = b.task_type) 
WHEN NOT MATCHED THEN 
[INSERT INTO TASK] 

또는 그것이 있어야 :

MERGE INTO TASK a 
USING (SELECT b.task_date FROM TASK b) 
ON (a.task_type = b.task_type) 
WHEN MATCHED THEN 
[] 
WHEN MATCHED THEN 
[INSERT INTO TASK] 

내가 번갈아

MERGE INTO TASK USING (select 1 from DUAL) . . . 

제안 마십시오 사용할 수 있습니다.

+0

단지 삽입이라면 select?를 사용하여 insert 문을 사용하는 것이 어떻겠습니까? – user75ponic

+0

@ user75ponic 두 가지 이유가 있습니다. 하나는 최소한의 변경으로 향후 업데이트를 수용하고 둘째로 Merge는 삽입보다 느릴 것으로 예상합니까? 그렇지 않다면, 그 이유는 무엇입니까? –

답변

3

귀하의 비즈니스 규칙은 DATE 및 TYPE에 일치하는 것을 나타냅니다. 코드에 두 가지 문제가 있습니다.

  1. USING 절은 일치 여부를 결정하는 데 필요한 모든 조건을 선택해야합니다.
  2. ON 절은 일치를 결정하는 데 필요한 모든 기준을 테스트해야합니다.

또한 기존 레코드를 업데이트 할 필요가없는 경우 WHEN MATCHED 분기를 생략 할 수 있습니다. 따라서 MERGE 문은 다음과 같이 표시되어야합니다.

merge into task 
using ( 
    select date '2017-05-08' as dt, 'BATTLE' as typ from dual union all 
    select date '2017-05-08' as dt, 'JUGGLE' as typ from dual union all 
    select date '2017-05-08' as dt, 'PLOT' as typ from dual) q 
on (task.task_date = q.dt 
    and task.task_type = q.typ) 
when not matched then 
    insert values (task_id_seq.nextval, q.dt, q.typ) 
/ 

데모. 이 시점 주어 ...

SQL> select * from task; 

    TASK_ID TASK_DATE TASK_TYPE 
---------- ---------- ---------- 
     1 2017-05-06 CLEAN 
     2 2017-05-06 BATTLE 
     3 2017-05-06 JUGGLE 
     4 2017-05-07 JUGGLE 
     5 2017-05-07 CLEAN 
     6 2017-05-07 NAP 
     7 2017-05-08 BATTLE 

7 rows selected. 
SQL> 

...는 두 개의 행을 삽입한다 상기 MERGE (데이터 소스의 하나의 행은 기존 행 일치).

SQL> merge into task 
    2 using ( 
    3  select date '2017-05-08' as dt, 'BATTLE' as typ from dual union all 
    4  select date '2017-05-08' as dt, 'JUGGLE' as typ from dual union all 
    5  select date '2017-05-08' as dt, 'PLOT' as typ from dual) q 
    6 on (task.task_date = q.dt 
    7  and task.task_type = q.typ) 
    8 when not matched then 
    9  insert values (task_id_seq.nextval, q.dt, q.typ) 
10/ 

2 rows merged. 

SQL> select * from task 
    2/

    TASK_ID TASK_DATE TASK_TYPE 
---------- ---------- ---------- 
     1 2017-05-06 CLEAN 
     2 2017-05-06 BATTLE 
     3 2017-05-06 JUGGLE 
     4 2017-05-07 JUGGLE 
     5 2017-05-07 CLEAN 
     6 2017-05-07 NAP 
     7 2017-05-08 BATTLE 
     9 2017-05-08 JUGGLE 
     10 2017-05-08 PLOT 

9 rows selected. 

SQL> 

데이터 소스는 완전히 명확하지 않다. 위의 예에서 DUAL을 사용하여 일련의 작업을 생성했습니다. 당신이 원하는 것은 어제의 세트에서 오늘 작업의 새로운 세트를 작성하는 경우 USING 절은 다음과 같이 보일 것이다 :

merge into task 
using ( 
    select trunc(sysdate) as dt, task_type as typ 
    from task 
    where task_date = trunc(sysdate) - 1) q 
on (task.task_date = q.dt 
    and task.task_type = q.typ) 
when not matched then 
    insert values (task_id_seq.nextval, q.dt, q.typ) 
/

를이 버전은 세 개의 행 삽입하기 전에 같은 시작 데이터를 사용하여 :

SQL> select * from task; 

    TASK_ID TASK_DATE TASK_TYPE 
---------- ---------- ---------- 
     1 2017-05-06 CLEAN 
     2 2017-05-06 BATTLE 
     3 2017-05-06 JUGGLE 
     4 2017-05-07 JUGGLE 
     5 2017-05-07 CLEAN 
     6 2017-05-07 NAP 
     7 2017-05-08 BATTLE 
     11 2017-05-08 CLEAN 
     12 2017-05-08 JUGGLE 
     13 2017-05-08 NAP 

10 rows selected. 

SQL>