에 대한 실행되지 :오라클 - 업데이트의 UPSERT 내가 업데이 트를 다음 또는 순간에 오라클 문을 삽입 사용하고 수정되지 않은 값
BEGIN
UPDATE DSMS
SET SURNAME = :SURNAME
WHERE DSM = :DSM;
IF (SQL%ROWCOUNT = 0) THEN
INSERT INTO DSMS
(DSM, SURNAME)
VALUES
(:DSM, :SURNAME);
END IF;
END;
이 데이터가 동일한 경우 업데이트 문이 더미 업데이트를 수행하는 것을 제외하고 잘 실행 제공된 매개 변수 값으로 사용하십시오. 정상적인 상황에서 더미 업데이트는 신경 쓰지 않지만 테이블의 트리거를 사용하여 업데이트 된 레코드를 캡처하고이 레코드를 자주 실행하면 트리거 및 트리거에 막대한 트래픽이 발생한다는 것을 의미하는 복제/동기화 시스템이이 테이블 위에 구축됩니다. 동기 시스템.
다음 코드를 사용하지 않고 업데이트 구문이 레코드를 업데이트하지 못하도록이 코드를 재구성하는 방법이 있습니까?이 코드에서는 매끄럽지 않고 어쩌면이 작업에 가장 효율적이지 않은 체크 코드를 사용하지 않습니까?
DECLARE
CNT NUMBER;
BEGIN
SELECT COUNT(1) INTO CNT FROM DSMS WHERE DSM = :DSM;
IF SQL%FOUND THEN
UPDATE DSMS
SET SURNAME = :SURNAME
WHERE DSM = :DSM
AND SURNAME != :SURNAME;
ELSE
INSERT INTO DSMS
(DSM, SURNAME)
VALUES
(:DSM, :SURNAME);
END IF;
END;
는 또한 문에 병합 사용했지만, 값이 (갱신 아무것도 수정하지 않고 삽입이 실행되지만, PK 위반이 발생) 수정되지 않은 경우는 업데이트가 작동하지 않습니다. 샘플 INTO
전체 MERGE :
CREATE TABLE DSMS(
dsm VARCHAR2(10) NOT NULL PRIMARY KEY,
surname VARCHAR2(10) NOT NULL
);
> Table created
-- :DSM = 'xx', :SURNAME = 'xx'
MERGE INTO DSMS D
USING (SELECT :DSM AS DSM,
:SURNAME AS SURNAME
FROM DUAL) V
ON (D.DSM = V.DSM)
WHEN MATCHED THEN
UPDATE
SET SURNAME = V.SURNAME
WHERE D.SURNAME <> V.SURNAME
WHEN NOT MATCHED THEN
INSERT (DSM, SURNAME)
VALUES (V.DSM, V.SURNAME);
> Ok - record inserted
-- :DSM = 'xx', :SURNAME = 'xx'
MERGE INTO DSMS D
USING (SELECT :DSM AS DSM,
:SURNAME AS SURNAME
FROM DUAL) V
ON (D.DSM = V.DSM)
WHEN MATCHED THEN
UPDATE
SET SURNAME = V.SURNAME
WHERE D.SURNAME <> V.SURNAME
WHEN NOT MATCHED THEN
INSERT (DSM, SURNAME)
VALUES (V.DSM, V.SURNAME);
> ORA-00001 - Unique constraint violated (PK violation)
그것은 UPDATE를 사용하는 오라클처럼 보이는 ... SQL의 %의 ROWCOUNT = 0 THEN 삽입하면 ... 내부 절에 병합을 검색 하시나요? 두 번째 MERGE INTO 문은 업데이트가 아무 것도 업데이트하지 않으므로 INSERT가 실행되므로 PK 위반이 발생합니다. 행이 이미 존재하기 때문에 값이 변경되지 않았기 때문입니다.
샘플에서'DSMS'을'TestMerge'로 대체하면 두 문장 모두 저에게 잘 돌아갑니다. – Quassnoi
@Quassnoi : 일부 Oracle DB 버전의 Oracle MERGE INTO 구현에서 버그에 대한 정보를 발견했습니다. 병합 명령을 두 번 실행하면 PK 위반이 발생하기 때문에 일부 버그가 발생할 수 있습니다. 샘플을 성공적으로 실행 한 OraDB 버전은 무엇입니까? 나는 10.2.0.1.0에있다 ... – Buthrakaur
나는 버전'10.2.0.1.0'도 실행 중이다. 여러분이 생성 한 샘플 테이블은'TestMerge'라고 불리우지 만,'MERGE' 통계에서는'DSMS' 테이블을 사용합니다 :'MERGE INTO DSMS D ...'. – Quassnoi