Oracle-merge 사용법 상세 설명

Oracle9i에서 MERGE 명령을 도입했습니다. SQL 문장에서 테이블에 inserts와 업데이트를 동시에 수행할 수 있습니다.MERGE 명령은 하나 이상의 데이터 원본에서 updating이나 inserting에서 하나 이상의 테이블로 줄을 선택합니다.Oracle 10g에서 MERGE는 다음과 같이 향상되었습니다.
 
 
UPDATE나 INSERT 자구에 WHERE 자구를 추가할 수 있습니다. 업데이트나 insert 동작이 일부 줄에 대한 처리를 건너뛸 수 있습니다.다음 예제에서는 테이블 NEWPRODUCTS에 따라 테이블 PRODUCTS 데이터를 업데이트하지만 필드가 모두 일치해야 합니다.
 
DE>SQL> MERGE INTO products p
    2 USING newproducts np
    3 ON (p.product_id = np.product_id)
    4 WHEN MATCHED THEN
    5 UPDATE
    6 SET p.product_name = np.product_name
    7 WHERE p.category = np.category;

    2 rows merged.

    SQL> SELECT * FROM products;

    PRODUCT_ID PRODUCT_NAME CATEGORY
    ---------- -------------------- ----------
    1501 VIVITAR 35MM ELECTRNCS
    1502 OLYMPUS CAMERA ELECTRNCS
    1600 PLAY GYM TOYS
    1601 LAMAZE TOYS
    1666 HARRY POTTER DVD
    SQL>
    SQL> rollback;DE>

 
 
 
이 예에서 제품 ID는 15021601과 1666은 ON 조건에 일치하지만 1666의 category는 일치하지 않는다.따라서 MERGE 명령은 두 줄의 데이터만 업데이트합니다.다음 예에서는 Updates 및 Inserts 자문에서 WHERE 자문을 사용하는 것을 보여 줍니다.
 
DE>SQL> MERGE INTO products p
    2 USING newproducts np
    3 ON (p.product_id = np.product_id)
    4 WHEN MATCHED THEN
    5 UPDATE
    6 SET p.product_name = np.product_name,
    7 p.category = np.category
    8 WHERE p.category = 'DVD'
    9 WHEN NOT MATCHED THEN
    10 INSERT
    11 VALUES (np.product_id, np.product_name, np.category)
    12 WHERE np.category != 'BOOKS'
    SQL> /

    1 row merged.

    SQL> SELECT * FROM products;

    PRODUCT_ID PRODUCT_NAME CATEGORY
    ---------- -------------------- ----------
    1501 VIVITAR 35MM ELECTRNCS
    1502 OLYMPUS IS50 ELECTRNCS
    1600 PLAY GYM TOYS
    1601 LAMAZE TOYS
    1666 HARRY POTTER TOYS

    SQL>DE>

 
 
WHERE 자구가 있기 때문에 INSERT는 ON 조건에 일치하지 않는 모든 줄을 표 PRODUCTS에 삽입하지 않았습니다.
3. 무조건 Inserts
 
너는 원본표와 목표표를 연결하지 않고 원본표의 데이터를 목표표에 삽입할 수 있다.이것은 네가 모든 줄을 목표표에 삽입하고 싶을 때 매우 유용하다.Oracle 10g은 현재 ON 조건에서 상수 필터 술어를 지원합니다.술어를 상수로 거르는 예를 들어 ON(1=0).다음 예제에서는 소스 테이블에서 테이블 PRODUCTS에 행을 삽입하고 이러한 행이 테이블 PRODUCTS에 있는지 확인하지 않습니다.
 
DE>SQL> MERGE INTO products p
    2 USING newproducts np
    3 ON (1=0)
    4 WHEN NOT MATCHED THEN
    5 INSERT
    6 VALUES (np.product_id, np.product_name, np.category)
    7 WHERE np.category = 'BOOKS'
    SQL> /

    1 row merged.

    SQL> SELECT * FROM products;

    PRODUCT_ID PRODUCT_NAME CATEGORY
    ---------- -------------------- ----------
    1501 VIVITAR 35MM ELECTRNCS
    1502 OLYMPUS IS50 ELECTRNCS
    1600 PLAY GYM TOYS
    1601 LAMAZE TOYS
    1666 HARRY POTTER DVD
    1700 WAIT INTERFACE BOOKS
    6 rows selected.
    SQL>DE>

 
 
 
4、새로 추가된 DELETE 자구
 
Oracle 10g의 MERGE는 데이터 작업을 수행할 때 행을 지울 수 있는 옵션을 제공합니다.너는 WHEN MATCHED THEN UPDATE 자구에 DELETE 자구를 포함할 수 있다.DELETE 자문에는 특정 조건에 맞는 행을 삭제하기 위한 WHERE 조건이 있어야 합니다.DELETE WHERE 조건과 일치하지만 ON 조건과 일치하지 않는 행은 테이블에서 삭제되지 않습니다.
 
다음 예는 DELETE 자구를 검증합니다.우리는 테이블 NEWPRODUCTS에서 테이블 PRODUCTS로 줄을 통합하지만, category가 ELECTRNCS인 줄을 삭제합니다.
 
DE>SQL> MERGE INTO products p
    2 USING newproducts np
    3 ON (p.product_id = np.product_id)
    4 WHEN MATCHED THEN
    5 UPDATE
    6 SET p.product_name = np.product_name,
    7 p.category = np.category
    8 DELETE WHERE (p.category = 'ELECTRNCS')
    9 WHEN NOT MATCHED THEN
    10 INSERT
    11 VALUES (np.product_id, np.product_name, np.category)
    SQL> /

    4 rows merged.

    SQL> SELECT * FROM products;

    PRODUCT_ID PRODUCT_NAME CATEGORY
    ---------- -------------------- ----------
    1501 VIVITAR 35MM ELECTRNCS
    1600 PLAY GYM TOYS
    1601 LAMAZE TOYS
    1666 HARRY POTTER TOYS
    1700 WAIT INTERFACE BOOKS
    SQL>DE>

 
 
 
제품 ID가 1502인 줄은 테이블 PRODUCTS에서 삭제됩니다. ON 조건과 DELETE WHERE 조건이 모두 일치하기 때문입니다.제품 ID가 1501인 줄은 DELETE WHERE 조건과 일치하지만 ON 조건과 일치하지 않기 때문에 삭제되지 않았습니다.제품 ID가 1700인 줄은 ON 조건과 일치하지 않기 때문에 표 PRODUCTS에 삽입됩니다.제품 ID가 1601과 1666인 줄은 ON 조건과 일치하지만 DELETE WHERE 조건과 일치하지 않기 때문에 표 NEWPRODUCTS의 값으로 업데이트되었습니다.
 
예2:
Insert/Update 대신 Merge Into 문이 Oracle에서의 응용 실전 동기:
Oracle에서 SQL 문을 사용하여 Insert/Update 작업을 직접 수행하려고 합니다.
설명:
SQL 문장을 작성할 때 우리는 Insert/Update를 동시에 진행하는 문장을 많이 만난다. 즉, 기록이 존재할 때 업데이트(Update)하고 데이터가 존재하지 않을 때 삽입(Insert)하는 것이다.
실전:
다음은 테이블 T가 있고 두 개의 필드가 있습니다. a, b. 테이블 T에 Insert/Update를 만들고 싶습니다. 존재하면 T에 있는 b의 값을 업데이트하고, 존재하지 않으면 기록을 삽입합니다.Microsoft의 SQL 구문에는 다음과 같은 SQL Server의 구문이 포함되어 있습니다.
if exists(select 1 from T where T.a='1001' ) update T set T.b=2 Where T.a='1001' else insert into T(a,b) values('1001',2);
상기 문장은 T표에 a='1001'의 기록이 존재하면 b의 값을 2로 설정하고 그렇지 않으면 Insert의 a='100', b=2의 기록을 T에 기록한다는 것을 나타낸다.
그러나 그 다음에 Oracle에서 문제가 생겼습니다. Oracle 9i 이후에 Merge into의 문장이 Insert와 Update를 동시에 진행할 수 있다는 것을 기억하십니까? Merge의 문법은 다음과 같습니다.
MERGE INTO table_name alias1 USING (table|view|sub_query) alias2 ON (join condition) WHEN MATCHED THEN     UPDATE table_name     SET col1 = col_val1,         col2     = col2_val WHEN NOT MATCHED THEN     INSERT (column_list) VALUES (column_values); 위의 문법은 모두가 쉽게 이해할 수 있겠지, 그럼 우리는 이상의 논리에 따라 다시 한 번 쓰자.
MERGE INTO T T1 USING (SELECT a,b FROM T WHERE t.a='1001') T2 ON ( T1.a=T2.a) WHEN MATCHED THEN   UPDATE SET T1.b = 2 WHEN NOT MATCHED THEN   INSERT (a,b) VALUES('1001',2); 위의 문구가 맞는 것 같은데, 실제로 이 문구는 업데이트만 할 수 있고 Insert는 할 수 없습니다. 오류는 어디에 있습니까?
사실 Oracle에서 Merge 문장은 원래 전체 표의 업데이트를 진행하는 데 사용되었다. 즉,ETL 도구가 비교적 자주 사용하는 문법인데 중심은Using에 있다.
Merge 구문을 중국어로 해석하면 다음과 같습니다.
Alias2에서 Select에 나온 데이터는 하나하나가 Alias1과 ON(join condition)을 비교하고 일치하면 업데이트하는 작업(Update)을 하고 일치하지 않으면 삽입 작업(Insert)을 한다.
따라서 엄밀히 말하면 "Insert와 Update 문법이 동시에 존재하는 Merge 문장에서 총 Insert/Update의 기록수는 바로 Using 문장에서alias2의 기록수이다."
위에 적힌 문장은 왜 Update만 할 수 있고 Insert는 할 수 없는지 설명하기에 충분하다. Select가 데이터를 얻지 못하기 때문에 어떻게 Insert를 할 수 있는지:)
다음에 정확한 문장으로 바꾸면 훨씬 쉽다. 다음과 같다.
MERGE INTO T T1 USING (SELECT '1001' AS a,2 AS b FROM dual) T2 ON ( T1.a=T2.a) WHEN MATCHED THEN   UPDATE SET T1.b = T2.b WHEN NOT MATCHED THEN   INSERT (a,b) VALUES(T2.a,T2.b); 질의 결과, OK!
참고:
만약 Merge 문장의 원리를 이해하지 못한다면 Merge 문장은 비교적 위험한 문장이다. 특히 기록을 하나만 갱신하고 싶을 때 무심결에 전체 표의 데이터를 업데이트할 수도 있다.땀!!!
내가 일찍이 범한 실수는 아래와 같다. 모두들 무슨 문제인지 알아차렸습니까?
MERGE INTO T T1 USING (SELECT Count(*) cnt FROM T WHERE T.a='1001') T2 ON (T2.cnt>0) WHEN MATCHED THEN   UPDATE SET T1.b = T2.b WHEN NOT MATCHED THEN   INSERT (a,b) VALUES(T2.a,T2.b);
 
1. UPDATE 또는 INSERT 자문은 옵션입니다.
 
2. UPDATE 및 INSERT 자구에 WHERE 자구를 추가할 수 있음
 
3. ON 조건에서 insert의 모든 줄을 목표 테이블에 연결하기 위해 상수 필터 술어를 사용합니다. 원본 테이블과 목표 테이블을 연결할 필요가 없습니다.
 
4、UPDATE 자구 뒤에 DELETE 자구와 함께 불필요한 줄을 제거할 수 있다
 
먼저 예제 테이블을 생성합니다.
 
DE>create table PRODUCTS
    (
    PRODUCT_ID INTEGER,
    PRODUCT_NAME VARCHAR2(60),
    CATEGORY VARCHAR2(60)
    );

    insert into PRODUCTS values (1501, 'VIVITAR 35MM', 'ELECTRNCS');
    insert into PRODUCTS values (1502, 'OLYMPUS IS50', 'ELECTRNCS');
    insert into PRODUCTS values (1600, 'PLAY GYM', 'TOYS');
    insert into PRODUCTS values (1601, 'LAMAZE', 'TOYS');
    insert into PRODUCTS values (1666, 'HARRY POTTER', 'DVD');
    commit;

    create table NEWPRODUCTS
    (
    PRODUCT_ID INTEGER,
    PRODUCT_NAME VARCHAR2(60),
    CATEGORY VARCHAR2(60)
    );

    insert into NEWPRODUCTS values (1502, 'OLYMPUS CAMERA', 'ELECTRNCS');
    insert into NEWPRODUCTS values (1601, 'LAMAZE', 'TOYS');
    insert into NEWPRODUCTS values (1666, 'HARRY POTTER', 'TOYS');
    insert into NEWPRODUCTS values (1700, 'WAIT INTERFACE', 'BOOKS');
    commit;DE>

1. 생략 가능한 UPDATE 또는 INSERT 자구
 
Oracle 9i에서 MERGE 문구는 INSERT와 UPDATE 자구를 동시에 지정해야 합니다.Oracle 10g에서는 UPDATE나 INSERT 자구 중 하나를 생략할 수 있습니다.다음 예는 표 NEWPRODUCTS에 따른 PRODUCTID 필드가 업데이트 테이블 PRODUCTS에 대한 정보와 일치하는지 여부:
 
DE>SQL> MERGE INTO products p
    2 USING newproducts np
    3 ON (p.product_id = np.product_id)
    4 WHEN MATCHED THEN
    5 UPDATE
    6 SET p.product_name = np.product_name,
    7 p.category = np.category;

    3 rows merged.

    SQL> SELECT * FROM products;

    PRODUCT_ID PRODUCT_NAME CATEGORY
    ---------- -------------------- ----------
    1501 VIVITAR 35MM ELECTRNCS
    1502 OLYMPUS CAMERA ELECTRNCS
    1600 PLAY GYM TOYS
    1601 LAMAZE TOYS
    1666 HARRY POTTER TOYS
    SQL>
    SQL> ROLLBACK;
    Rollback complete.
    SQL>DE>

 
 
 
위의 예에서 MERGE 문구는 제품 id가 1502, 1601, 1666인 줄에 영향을 미친다.그것들의 제품 이름과 종류는 표 newproducts의 값으로 업데이트되었습니다.다음 예는 UPDATE 자구를 생략하고 표 NEWPRODUCTS의 새로운 PRODUCT 를ID가 테이블 PRODUCTS에 삽입되어 두 테이블에서 PRODUCT 와 일치할 수 있음ID의 데이터가 처리되지 않습니다.이 예에서 프로듀스를 보실 수 있습니다ID=1700의 행이 테이블 PRODUCTS에 삽입됩니다.
 
DE>SQL> MERGE INTO products p
    2 USING newproducts np
    3 ON (p.product_id = np.product_id)
    4 WHEN NOT MATCHED THEN
    5 INSERT
    6 VALUES (np.product_id, np.product_name,
    7 np.category);

    1 row merged.

    SQL> SELECT * FROM products;

    PRODUCT_ID PRODUCT_NAME CATEGORY
    ---------- -------------------- ----------
    1501 VIVITAR 35MM ELECTRNCS
    1502 OLYMPUS IS50 ELECTRNCS
    1600 PLAY GYM TOYS
    1601 LAMAZE TOYS
    1666 HARRY POTTER DVD
    1700 WAIT INTERFACE BOOKSDE>

2. 조건부 Updates 및 Inserts 자문

좋은 웹페이지 즐겨찾기