Oracle ORA-00997 오류 원인과 해결 방법 완벽 가이드

ORA-00997
2026년 06월 25일 | DBMS Error 가이드

이 글에서 다루는 내용

ORA-00997 에러의 원인 분석, 해결 SQL, 예방 방법을 실무 관점에서 정리합니다.

ORA-00997 illegal use of LONG datatype 는?

ORA-00997 에러는 Oracle 데이터베이스에서 LONG 또는 LONG RAW 데이터 타입을 허용되지 않는 방식으로 사용하려 할 때 발생하는 오류입니다. LONG 타입은 Oracle의 레거시 데이터 타입으로, 최대 2GB까지 문자 데이터를 저장할 수 있지만, SQL 함수 적용, 비교 연산, 서브쿼리, DISTINCT, GROUP BY, ORDER BY 등 다양한 SQL 구문에서 사용이 제한됩니다. Oracle은 오래전부터 LONG 타입 대신 CLOB/BLOB을 사용할 것을 권장하고 있으며, 이 에러는 주로 레거시 시스템 유지보수나 마이그레이션 작업 중 빈번하게 마주치게 됩니다.


주요 발생 원인

  • LONG 컬럼에 SQL 함수 또는 연산자 직접 적용

LONG 데이터 타입은 SUBSTR, UPPER, LENGTH, LIKE 등 대부분의 SQL 내장 함수와 비교 연산자(=, >, <)를 직접 사용할 수 없습니다. 예를 들어, WHERE long_column LIKE '%keyword%' 와 같은 구문을 사용하면 ORA-00997이 발생합니다. 이는 Oracle 내부적으로 LONG 타입이 고정 크기 메모리 구조가 아닌 스트림 방식으로 처리되기 때문에 일반적인 연산 처리가 불가능하기 때문입니다.

  • LONG 컬럼을 포함한 INSERT ... AS SELECT 또는 CTAS(Create Table As Select) 사용

LONG 컬럼을 다른 테이블로 복사하거나, CREATE TABLE ... AS SELECT 구문을 사용할 때 특정 조건에서 ORA-00997이 발생할 수 있습니다. 특히 LONG 컬럼과 함께 다른 컬럼에 함수나 변환 작업을 적용하는 혼합 SELECT 문에서 Oracle이 LONG 타입의 처리 방식에 제약을 걸기 때문입니다. 이 경우 단순 복사라도 LONG 타입의 특수성으로 인해 예상치 못한 에러가 발생할 수 있습니다.

  • LONG 컬럼을 포함한 뷰(View) 생성 또는 서브쿼리 활용

LONG 컬럼이 포함된 테이블을 기반으로 뷰를 생성하거나, 서브쿼리 내에서 LONG 컬럼을 SELECT 하는 경우 제약이 발생합니다. Oracle은 LONG 타입 컬럼이 포함된 경우 인라인 뷰나 서브쿼리의 결과를 다시 상위 쿼리에서 필터링하거나 조작하는 것을 허용하지 않는 경우가 많습니다. 또한 GROUP BY, ORDER BY, DISTINCT 절에 LONG 컬럼을 포함시키는 것 역시 이 에러의 원인이 됩니다.


해결 방법

해결책 1: LONG 컬럼을 TO_LOB() 함수로 변환 후 조작

LONG 컬럼을 직접 조작하는 대신, TO_LOB() 함수를 활용하여 CLOB으로 변환한 뒤 원하는 SQL 함수를 적용합니다.

-- 잘못된 예시 (ORA-00997 발생)
SELECT SUBSTR(long_column, 1, 100)
FROM legacy_table;

-- 올바른 예시: TO_LOB()을 활용한 CLOB 변환 후 처리
SELECT SUBSTR(TO_LOB(long_column), 1, 100)
FROM legacy_table;

-- LIKE 검색도 동일하게 적용
SELECT *
FROM legacy_table
WHERE DBMS_LOB.INSTR(TO_LOB(long_column), 'keyword') > 0;

해결책 2: LONG 컬럼을 CLOB으로 마이그레이션 (근본적 해결)

장기적으로 가장 효과적인 방법은 LONG 컬럼을 CLOB으로 변환하는 것입니다.

-- 1단계: 임시 CLOB 컬럼 추가
ALTER TABLE legacy_table ADD (long_column_clob CLOB);

-- 2단계: 데이터 CLOB으로 복사
UPDATE legacy_table
SET long_column_clob = TO_LOB(long_column);

COMMIT;

-- 3단계: 기존 LONG 컬럼 삭제
ALTER TABLE legacy_table DROP COLUMN long_column;

-- 4단계: 새 CLOB 컬럼 이름 변경
ALTER TABLE legacy_table RENAME COLUMN long_column_clob TO long_column;

-- 변환 확인
SELECT column_name, data_type
FROM user_tab_columns
WHERE table_name = 'LEGACY_TABLE';

해결책 3: CTAS(Create Table As Select) 시 TO_LOB 활용

LONG 컬럼을 포함한 테이블을 새로 생성할 때는 반드시 TO_LOB()을 사용합니다.

-- 잘못된 예시 (ORA-00997 발생 가능)
CREATE TABLE new_table AS
SELECT id, long_column
FROM legacy_table;

-- 올바른 예시
CREATE TABLE new_table AS
SELECT id, TO_LOB(long_column) AS long_column
FROM legacy_table;

-- INSERT INTO ... SELECT 시에도 동일하게 적용
INSERT INTO new_table (id, clob_column)
SELECT id, TO_LOB(long_column)
FROM legacy_table;

COMMIT;

해결책 4: PL/SQL을 활용한 LONG 데이터 처리

SQL 레벨에서 처리가 불가능한 경우, PL/SQL을 통해 LONG 데이터를 VARCHAR2 또는 CLOB 변수로 읽어 처리합니다.

DECLARE
    v_long_data  LONG;
    v_clob_data  CLOB;
    v_result     VARCHAR2(4000);
BEGIN
    -- LONG 컬럼을 PL/SQL 변수로 읽기 (PL/SQL에서는 LONG 변수 사용 가능)
    SELECT long_column
    INTO v_long_data
    FROM legacy_table
    WHERE id = 1;

    -- LONG을 CLOB으로 변환 처리
    v_clob_data := TO_CLOB(v_long_data);

    -- CLOB에 대한 함수 적용
    v_result := DBMS_LOB.SUBSTR(v_clob_data, 200, 1);

    DBMS_OUTPUT.PUT_LINE('결과: ' || v_result);
END;
/

예방 방법

  • 신규 테이블 설계 시 LONG/LONG RAW 타입 사용 금지 정책 수립

Oracle 공식 문서에서도 LONG 타입은 하위 호환성 유지를 위해서만 남아 있는 Deprecated 기능임을 명시하고 있습니다. DDL 리뷰 프로세스에 LONG 타입 사용 금지 체크를 포함시키고, 대용량 문자 데이터는 반드시 CLOB, 대용량 바이너리 데이터는 BLOB을 사용하도록 코딩 표준을 수립해야 합니다. 기존 시스템의 LONG 컬럼은 연간 마이그레이션 계획에 포함시켜 점진적으로 CLOB으로 전환하는 것을 권장합니다.

```sql

-- 데이터베이스 내 LONG 타입 컬럼 전수 조사 쿼리

SELECT owner, table_name, column_name, data_type

FROM dba_tab_columns

WHERE data_type IN ('LONG', 'LONG RAW')

ORDER BY owner, table_name;

```

  • 애플리케이션 개발 단계에서 LONG 컬럼 접근 시 TO_LOB() 래퍼 함수 표준화

레거시 시스템에서 LONG 컬럼을 즉시 CLOB으로 전환하기 어려운 경우, 해당 컬럼을 SELECT하는 모든 쿼리에 TO_LOB() 래퍼를 적용하는 것을 팀 내 SQL 작성 표준으로 정의합니다. 뷰(View)를 활용하여 LONG 컬럼을 CLOB으로 노출하는 추상화 레이어를 만들면 애플리케이션 코드 수정 없이 하위 레이어에서 일괄 처리가 가능합니다.

```sql

-- LONG 컬럼을 CLOB으로 노출하는 래퍼 뷰 생성

CREATE OR REPLACE VIEW legacy_table_v AS

SELECT id,

created_date,

TO_LOB(long_column) AS long_column

FROM legacy_table;

```


관련 에러

  • ORA-00932: inconsistent datatypes — LONG 타입을 다른 데이터 타입과 직접 비교하거나 연산할 때 함께 발생하는 경우가 많습니다.
  • ORA-00939: too many arguments for function — LONG 타입을 지원하지 않는 함수에 LONG 컬럼을 인자로 넘길 때 발생할 수 있습니다.
  • ORA-22998: CLOB or NCLOB in multibyte character set not supported — LONG을 CLOB으로 변환하는 과정에서 캐릭터셋 문제로 발생할 수 있으며, LONG 관련 마이그레이션 작업 시 주의가 필요합니다.
  • ORA-01461: can bind a LONG value only for insert into a LONG column — LONG 타입 바인드 변수를 LONG이 아닌 컬럼에 삽입하려 할 때 발생하며, LONG 처리 관련 작업에서 ORA-00997과 함께 마주칠 수 있는 에러입니다.

DBMS 에러 코드 시리즈

주요 DBMS error code를 정리하는 시리즈입니다.
블로그 홈에서 다른 에러도 확인하세요.

본 포스트는 AI가 생성한 기술 가이드입니다. 운영 환경 적용 전 충분한 검토를 권장합니다.

댓글 남기기