데이터 타입에 따른 비교 문의 드립니다.. 0 7 3,965

by 동동동 [Oracle 기초] oracle datatype [2022.03.17 15:27:22]


안녕하세요..트리거로 수정된 데이터가 있을시 로그를 쌓으려고 하는데요...

데이터 타입이 Date나 BLOB 인 경우 Null체크 및 비교를 어떻게 해야 하는지요??

String 타입이나 Number 는

IF NVL(:OLD.EMAIL, 'x') != NVL(:NEW.EMAIL, 'x') OR  NVL(:OLD.NUM, 0) != NVL(:NEW.NUM, 0) THEN 이렇게 비교하면 되는데..

Date나 BLOB 인 경우 변경여부를 어떻게 체크해야 하는지요?

 

아..date 타입은 문자로 변환 후 비교하면 되겠군요..

NVL(TO_CHAR(:OLD.CHGDT, 'YYYYMMDDHH24MISS'), 'X') !=  NVL(TO_CHAR(:NEW.CHGDT, 'YYYYMMDDHH24MISS'), 'X')

 

수정..

질문을 올리고 인터넷을 검색해 보니 DBMS_LOB.COMPARE 로 비교가 가능하네요...

 

정리 하자면 ..

 

NVL(:OLD.EMAIL, 'x') != NVL(:NEW.EMAIL, 'x')    --문자타입 비교

NVL(:OLD.NUM, 0) != NVL(:NEW.NUM, 0)    -- 숫자타입 비교

NVL(TO_CHAR(:OLD.CHGDT, 'YYYYMMDDHH24MISS'), 'X') !=  NVL(TO_CHAR(:NEW.CHGDT, 'YYYYMMDDHH24MISS'), 'X')    -- Date타입 비교

DBMS_LOB.COMPARE(:OLD.IMG,  :NEW.IMG) != 0    -- LOB타입 비교

 

이런식으로 비교 하는게 맞는 건가요??

 

by 우주민 [2022.03.17 16:03:31]

where 절 비교를 위한거면 is null // is not null 로 조건을 주지 않을까요?


by 동동동 [2022.03.17 17:11:56]

답글 감사드립니다..


by 마농 [2022.03.17 16:47:45]

NVL 사용시에는 대체값인 'X' 나 0 등이 원래 입력 가능한 값인 경우는 없는지 확인이 필요합니다.
- 'X' 를 NULL 로 업데이트 한다던가. NULL 을 'X' 로 업데이트 한다던가
- 0 를 NULL 로 업데이트 한다던가. NULL 을 0 으로 업데이트 한다던가
DBMS_LOB.COMPARE 함수도 NULL 이 포함된 비교는 안됩니다.


by 동동동 [2022.03.17 17:17:46]

답글 감사드립니다..

경우의 수가 기존값을 다른값으로 변경하거나 지우는 경우(Null) 밖에 없을 것 같습니다..

NVL의 대체값은 사용되지 않습니다..

 

이미지 체크가 문제네요...

이미지를 지우거나(not null => Null),

기존에 없던 (null 이던 값을) 이미지를 추가 하거나

기존 이미지(not null이던 값을) 를 다른 이미지로 변경하는 경우를 체크 해야 하는데...


by 마농 [2022.03.17 17:49:45]

NULL 에서 NULL 로 가는 경우는 없다고 가정한다면.
양쪽다 NULL 인 경우는 없다고 가정한다면.
LNNVL 함수를 이용 할 수 있습니다.
LNNVL(:OLD.email = :NEW.email)
LNNVL(:OLD.num   = :NEW.num  )
LNNVL(:OLD.chgdt = :NEW.chgdt)
LNNVL(DBMS_LOB.COMPARE(:OLD.img, :NEW.img) = 0)


by 동동동 [2022.03.17 18:40:29]

마농님 답변 감사드립니다...함수를 또하나 새로 배우네요..^^

아..생각해 보니 값을 입력안했으면 트리거에서 Null에서 Null 체크도 해야 하네요....ㅠㅠ

 

WITH TMP AS (
SELECT 'Null에서 문자로' TXT, NULL ASIS, '123' TOBE FROM DUAL
UNION ALL
SELECT '문자에서 Null로' TXT, 'AAA' ASIS, NULL TOBE FROM DUAL
UNION ALL
SELECT 'Null에서 Null로' TXT, NULL ASIS, NULL TOBE FROM DUAL
UNION ALL
SELECT '동일 문자로' TXT, '123' ASIS, '123' TOBE FROM DUAL
UNION ALL
SELECT '다른 문자로' TXT, '123' ASIS, '456' TOBE FROM DUAL
)
--SELECT * FROM TMP
--WHERE LNNVL(ASIS = TOBE);
SELECT TMP.*, LNNVL(ASIS = TOBE) FROM TMP
;

이렇게 해봤는데 이게 최선인지 확신이 안서네요..ㅠㅠ
IF NVL(:OLD.EMAIL, 'x') != NVL(:NEW.EMAIL, 'x')    --문자타입 비교
   OR
   NVL(:OLD.NUM, 0) != NVL(:NEW.NUM, 0)    -- 숫자타입 비교
   OR
   NVL(TO_CHAR(:OLD.CHGDT, 'YYYYMMDDHH24MISS'), 'X') !=  NVL(TO_CHAR(:NEW.CHGDT, 'YYYYMMDDHH24MISS'), 'X')    -- Date타입 비교
   OR
   ((:OLD.IMG IS NOT NULL AND :NEW.IMG IS NOT NULL AND DBMS_LOB.COMPARE(:OLD.IMG, :NEW.IMG) != 0)    -- LOB타입 비교
    OR
    (:OLD.IMG IS NOT NULL AND :NEW.IMG IS NULL)
    OR
    (:OLD.IMG IS NULL AND :NEW.IMG IS NOT NULL))   
THEN
...
END IF;

 


by 랄랄라 [2022.05.20 16:41:13]

저는 String인 경우 아래와 같이 비교하는데
그 외의 데이터타입은 고민이긴 하네요.
DBMS_LOB.COMPARE는 성능이 괜찮나요??
0 = CASE WHEN (%1$s IS NULL AND %2$s IS NULL) OR %1$s = %2$s THEN 1 ELSE 0 END

댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입