프로그램을 다루면서 Oracle DB에 데이터를 넣을 때....
ORA-01461: LONG 값은 LONG 열에만 입력할 수 있습니다 라는 오류를 만났다면,
첫 번째로 의심해야 하는 내용은 VARCHAR2(4000)으로 잡혀있는 컬럼에 그 이상의 값이 들어간 것!
그리고 두 번째로 의심해야 될 내용은 CLOB에 들어가는 데이터가 CLOB의 형태로 들어가지 않는다는 것.
처음에 저 오류를 마주했을 때는 데이터 타입이 VARCHAR2(4000)으로 잡혀있었나? 하며 DB 구조를 살펴보니
CLOB이라고 너무나도 당연하게 써 있는 것에 조금 벙쩌있었져 ㅠ_ㅠ CLOB이면서 왜 데이터를 받지를 못하니...
Editor를 사용하여 HTML 태그가 들어간다거나 정~~~말 긴 글을 입력하게 되는 경우
이런 오류를 본 적이 있다면 현재 쿼리가 어떻게 짜여져 있는 지 살펴볼 필요가 있습니다.
PreparedStatement 또는 변수를 직접 쿼리 내용으로 받아서 사용하는 등의 쿼리 방식으로는
CLOB으로 들어가야 할 데이터가 Varchar2 Type으로 들어가 버립니다. ㅠㅠㅠㅠ
오류를 해결하려고 찾아보니 LOB 공간을 비워둔 후 다시 넣어주는 방식으로 입력할 수 있음을 알아냈습니다.
그럼 LOB 공간을 비워둔 후 비워진 공간에 LOB (CLOB, BLOB) 데이터를 담을 수 있도록 하는 쿼리를 짜보도록 하겠습니다.
이 쿼리의 핵심은 바로 EMPTY_CLOB() (BLOB을 사용하는 테이블에서는 EMPTY_BLOB()) 함수입니다.
EMPTY_CLOB() 또는 EMPTY_BLOB() 함수는 LOB 변수를 초기화하고 사용하기 위해서 공백 LOB 위치를 반환하는 함수입니다.
LOB 타입의 데이터를 넣기 위해서는 이 속성을 초기화시켜줘야 한다고 하네요~
그럼 간단한 예제로 LOB 타입을 초기화 시킨 후에 제가 넣고자 하는 CLOB 데이터를 넣도록 하는 쿼리를 작성해봅시다!
1. CLOB을 제외한 나머지 데이터는 일반적으로 입력하고 CLOB이 들어갈 자리에 EMPTY_CLOB()으로 초기화 시켜줍니다.
INSERT INTO TBL_TEMP
(NO, TITLE, CONTENT, GUBUN, REGISTER_DAY, FILENAME)
SELECT NVL(MAX(NO), 0) + 1, ?, EMPTY_CLOB(), ?, SYSDATE, ?
FROM TBL_TEST
간단하게 설명드리자면 Prepared statement 방식의 쿼리로 작성되었고, CONTENT 컬럼을 CLOB 데이터로 넣기 위해서
EMPTY_CLOB() 을 통해 초기화를 시켜주는 쿼리입니다.
2. 방금 입력한 데이터의 SEQ를 찾아옵니다.
SELECT /*+ INDEX_DESC(TBL_TEMP IDX_TBL_TEMP_PK) */
NO
FROM TBL_TEMP
WHERE ROWNUM = 1
CLOB 타입의 데이터를 넣기 위해서 비워둔 상태이기때문에 UPDATE 하기 위해서 최근 입력 데이터를 조회합니다.
3. 비워둔 CLOB 공간에 원하는 데이터를 넣어줍니다.
UPDATE TBL_TEMP SET CONTENT = ? WHERE NO = ?
두 번째 변수에 2번에서 조회한 최근 입력 SEQ 번호를 넣어주고, 첫 번째 변수에 넣고자 했던 데이터를 넣어주면 됩니다.
이렇게 쿼리를 3개나 써야하는 점이 귀찮으시면 프로시저를 활용하시면 한 번에 해결이 가능하지만...
위에 작성한 내용처럼 일반 쿼리를 사용하셔서 해결하실때는 반드시 트랜잭션을 사용하셔서 데이터 무결성을 유지하셔야 합니다 ㅋ_ㅋ
'DataBase > ORACLE' 카테고리의 다른 글
[ORACLE] 객체 참조를 위한 SYNONYM 생성 및 사용 방법 (0) | 2021.11.29 |
---|---|
[Oracle] 순위 결정을 위한 ROW_NUMBER, RANK, DENSE_RANK 함수 사용법 비교 (0) | 2021.01.27 |
[Oracle] 19c Upgrade : 전환 시 고려사항 (0) | 2020.10.11 |
[Oracle] 특정 값 기준으로 정렬하기 (0) | 2020.03.31 |
계층형 메뉴 트리 정렬하기 (3) | 2012.12.31 |