티스토리 뷰
1. 오류 개요
PostgreSQL과 MyBatis를 사용하여 데이터베이스 작업을 수행하는 중 "invalid input syntax for type numeric" 오류가 발생하였다.
2. 오류 발생 위치 및 원인 분석
2.1 오류 발생 위치
오류가 발생한 위치는 MyBatis SQL을 선언한 XML 파일 내의 쿼리에서 확인되었다.
문제 발생 쿼리 (일부)
update test_table
set num = nullif(#{paramNum}, '')::numeric
where id = #{id}
2.2 오류 메시지 및 원인 분석
오류 메시지: invalid input syntax for type numeric : ""
파라미터 paramNum이 빈 문자열 ('')로 전달되는 경우 발생
이미 nullif(파라미터, '') 함수를 사용하여 빈 문자열을 NULL로 변환하는 처리 적용
그러나, 동일한 SQL 문 내의 INSERT 문에서 nullif 처리가 누락된 것이 원인으로 확인됨
3. 상세 분석
PostgreSQL은 Oracle의 MERGE INTO 구문을 지원하지 않기 때문에 UPSERT 방식으로 데이터를 갱신한다. 해당 코드에서 다음과 같은 WITH upsert 구문이 사용되었다.
쿼리 내용 (상세)
WITH upsert AS (
UPDATE test_table
SET num = nullif(#{paramNum}, '')::numeric
WHERE id = #{id}
)
INSERT INTO test_table (num, id)
SELECT #{paramNum}::numeric, #{id}
WHERE NOT EXISTS (SELECT * FROM upsert)
3.1 문제 발생 원인
UPDATE 문에서는 nullif(#{paramNum}, '')::numeric 처리를 적용하여 빈 문자열('')이 NULL로 변환됨.
그러나 INSERT 문에서는 #{paramNum}::numeric로 직접 변환을 수행하면서 빈 문자열('')이 numeric 타입으로 캐스팅될 때 오류 발생.
MyBatis는 쿼리를 한 줄씩 검증하며 실행하므로, 조건문 없이 그대로 INSERT 문이 생성되면서 오류가 발생함.
<if test=""> 구문을 사용하여 실행 여부를 제어하면, 동일한 상황에서 오류를 방지할 수 있음.
4. 해결 방법
4.1 INSERT 문에서도 nullif 적용
INSERT INTO test_table (num, id)
SELECT nullif(#{paramNum}, '')::numeric, #{id}
WHERE NOT EXISTS (SELECT * FROM upsert)
4.2 <if test=""> 적용하여 조건부 실행
<if test="paramNum != null and paramNum != ''">
INSERT INTO test_table (num, id)
SELECT #{paramNum}::numeric, #{id}
WHERE NOT EXISTS (SELECT * FROM upsert)
</if>
5. 결론
numeric 타입의 컬럼에 빈 문자열이 입력되면 invalid input syntax for type numeric 오류가 발생할 수 있음.
nullif(#{paramNum}, '')::numeric 함수를 UPDATE뿐만 아니라 INSERT에도 적용하여 해결 가능.
<if test=""> 구문을 활용하여 빈 문자열 입력 시 INSERT 문이 생성되지 않도록 제어 가능.
해당 방식 적용 후 동일한 오류가 발생하지 않음을 확인함.
'DB' 카테고리의 다른 글
oracle 서브쿼리 rownum 조회시 ORA-00904 invalid identifier 원인파악 (0) | 2022.02.24 |
---|---|
[oracle 설정] UNDO tablespace 사용량 급증 현상 해결 (0) | 2020.12.22 |
[SQL] 문자형 비교연산자 (0) | 2020.07.15 |
[oracle] SQL 리터럴 변수와 바인드 변수 (0) | 2020.07.15 |
[DB] SQL 다국어 데이터 깨짐 현상 해결 (0) | 2020.05.15 |
- Total
- Today
- Yesterday
- Linux
- 깨짐
- SSL
- Windows
- IMAGE
- abstractcauchorequest
- spring
- tomcat
- gradle
- docker
- 컨테이너
- Oracle
- SQL
- jQuery
- standardmultiparthttpservletrequest
- React
- JPA
- Git
- SpringBoot
- parse
- mybatis
- web
- Java
- 날짜
- vscode
- TLS
- html
- Eclipse
- JSON
- WAS
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |