원문1 : https://javafreak.tistory.com/98
원문2 : http://egloos.zum.com/realcool/v/2585694
SQLInjection 을 막기 위해,
PreparedStatement 를 사용하는 것이 기본이겠죠.
DB 칼럼에 varchar2(4000) 이 있고,
한글 2000 자를 insert 또는 update 하려 할 때..
에러가 발생합니다, 글자를 너무 많이 입력했다공..
이것은, 오라클이..
setString() 을 사용할 때 한글을 UTF-8 로 자동변환 하면서,
한글 1글자를 3bytes 로 인식하기 때문이라네요.
이걸 JDBC 버그라 말하기도 하는데,
Statement 를 사용할 때는 setString() 으로 진행해도,
한글 2000자가 잘 들어가집니다.
물론, PreparedStatement 라도 ? 대신 파라미터를 넣는 방식이 아니고,
sql 문 자체에 한글 2000자를 넣어 버리면
Statement 를 사용할 때의 방식 처럼 정상 처리됩니다.
이를테면 String sql = "... "+str4000bytes+"..." 처럼요.
그러나 이런 방식은 칼럼이 여럿인 경우,
오라클의 sql 문 파싱이 무제한이 아니다 보니,
간헐적으로 오류가 발생할 수 있습니다.
그리고 SQLInjection 에도 취약하구요.
DB 가 NVarchar2() 로 세팅되었다면 문제 없을 수도..
이걸 피하는 해법이..
setCharacterStream() 사용하는 거라네요.
예전에 long 이나 Clob, Blob 이용시 사용하던 메소드입니다.
이러면 한글을 1byte 단위로 쪼개기 때문에,
우리가 익히 알고 있듯이
한글 1글자 당 2bytes 로 인식하는 거겠죠.
그런데, varchar2(4000) 인 칼럼이 하나의 테이블에 여럿 있다면..
a, b, c 칼럼이 varchar2(4000) 이라 할 때,
어떤 때는 a 칼럼에 들어갈 내용이 b 칼럼에 들어가는 식으로
제멋대로 데이타가 들어가진다는 건데..
이걸 피하려면 varchar2(4000) 대신에,
clob 이나 blob 을 이용하는 겁니다.
이 때는 여러 칼럼이 clob 이나 blob 이라 해도,
순서 오류 없이 제 칼럼에 정확하게 들어갑니다.
이제는 varchar2(4000) 과 같이 하는 것은 포기해야 하겠습니다.
substrb(?,0,4000) 를 이야기하는 분이 있던데..
oracle 에 파라미터가 전달된 다음에 byte 로 4,000 을 끊는거라서,
파라미터 전달될 때 문자열 길이 관련 에러가 납니다.
그리고, 간혹 4천 바이트를 넘기는 문자열이 들어갈 수 있으니..
파라미터 세팅 전에 4천 바이트 체크하는 로직을 넣는 것이 필요합니다.
java 는 n-byte 가 기본적으로 지원되기 때문에,
byte[] 에 넣어서 length 를 구하고 4천을 넘기면,
new String 으로 4천 바이트 까지 잘라서 다시 담아야 합니다.
String stringOver4000 = "...";
byte[] bs = stringOver4000.getBytes();
if(bs.length>4000) StringOver4000 = new String(stringOver4000,0,4000)
.Fine.
'Server Oriented > Java & JSP' 카테고리의 다른 글
기상청 초단기예보 API 와 날씨누리 홈페이지 강수량 차이.. (1) | 2022.08.09 |
---|---|
PreparedStatement 의 clearParameters() 는 불필요..? (1) | 2022.06.24 |
Collections 안에 다른 Collections 을 넣었을 때의 GC (1) | 2022.06.21 |
ORA-22990: LOB 위치는 트랜잭션을 걸칠 수 없습니다 (0) | 2021.11.15 |
PreparedStatement SQL 문에 ? 를 적용할 수 없는 것 (0) | 2021.09.29 |