본문 바로가기
DataBase/ORACLE

ORACLE에서 LONG 열에만 입력할 수 있다고 할 때는?

by ojava 2013. 2. 4.
반응형


프로그램을 다루면서 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개나 써야하는 점이 귀찮으시면 프로시저를 활용하시면 한 번에 해결이 가능하지만...


위에 작성한 내용처럼 일반 쿼리를 사용하셔서 해결하실때는 반드시 트랜잭션을 사용하셔서 데이터 무결성을 유지하셔야 합니다 ㅋ_





 



반응형