현상
INSERT INTO SELECT 구문 수행 시 NUMBER 데이터 타입 소수점이 누락되어 insert 되어, insert된 데이터와 select된 데이터가 상이한 현상이 발생하였습니다.
예시
•
SELECT 결과 값: 0.0912721331678228063770232444931240111963
•
INSERT 결과 값: 0
재현 시나리오
--1. 테이블 DDL
CREATE TABLE T1 (
CD VARCHAR(2) NOT NULL,
RATE NUMBER(26,17) DEFAULT 0 NOT NULL
);
CREATE TABLE T2 (
CD VARCHAR(2) NOT NULL,
GUBUN VARCHAR(1) NOT NULL,
AMT1 NUMBER(28,8) DEFAULT 0 NOT NULL
);
CREATE TABLE T3 (
CD VARCHAR(2) NOT NULL,
AMT2 NUMBER(28,8) DEFAULT 0 NOT NULL
);
INSERT INTO T2 VALUES (1, 1, 2054250000000);
INSERT INTO T3 VALUES (1, 187495779560);
commit;
--2. INSERT
INSERT INTO T1
SELECT A.CD
, CASE WHEN C.YN = 'Y' THEN 0
ELSE B.AMT2 / A.AMT1 END AS RATE
FROM T2 A
JOIN T3 B
ON A.CD = B.CD
LEFT OUTER JOIN (
SELECT 'Y' AS YN,
CD,
AMT1
FROM T2
WHERE GUBUN = 2
) C
ON C.CD = A.CD
;
--3. 결과 값
--SELECT 결과
#RATE
0.0912721331678228063770232444931240111963
--INSERT 결과
#RATE
0
SQL
복사
원인
292944a 패치의 side effect로 select와 insert 동작 방식이 아래와 같이 상이하게 적용되어 해당 현상이 발생하였습니다.
•
select 동작 방식: select절의 CASE 함수에 사용된 C.YN은 상수값 'Y'로부터 유래한 컬럼이지만, outer join에 의해 NULL 값을 가질 수 있기 때문에 상수로 취급 하지 않습니다.
•
insert 동작 방식: insert into select의 하드 파싱을 수행할 때는 outer join 여부와 무관하게 C.YN을 상수값으로 취급합니다.
참고
292944a 패치: multi-insert문 하드파싱 시의 메모리 사용량을 개선하는 패치
해결
개선된 패치를 적용해 해결합니다. (적용패치: 292944b )
주의
티맥스티베로에서 제공하는 기술지원을 통해 패치를 적용합니다.
참고
select절의 CASE 함수에 사용된 상수 값을 캐싱하도록 쿼리 수정하여 우회 가능합니다.
INSERT INTO T1
SELECT A.CD
, CASE WHEN C.YN = 'Y' THEN 0
ELSE B.AMT2 / A.AMT1 END AS RATE
FROM T2 A
JOIN T3 B
ON A.CD = B.CD
LEFT OUTER JOIN (
SELECT (SELECT 'Y' FROM DUAL) AS YN,
CD,
AMT1
FROM T2
WHERE GUBUN = 2
) C
ON C.CD = A.CD
;
SQL
복사