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

ORA-01756
2026년 07월 30일 | DBMS Error 가이드

이 글에서 다루는 내용

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

ORA-01756 quoted string not properly terminated 는?

ORA-01756 에러는 Oracle SQL 또는 PL/SQL 구문에서 문자열 리터럴을 감싸는 따옴표(작은따옴표)가 제대로 닫히지 않았을 때 발생하는 파싱 오류입니다. Oracle 파서가 SQL 문장을 해석하는 도중 시작된 따옴표에 대응하는 종료 따옴표를 찾지 못하면 이 에러를 던집니다. 주로 동적 SQL 생성, 애플리케이션에서 SQL 문자열 조합, 또는 특수문자가 포함된 데이터를 삽입·조회할 때 빈번하게 나타납니다.


주요 발생 원인

1. 문자열 내부의 작은따옴표(‘) 이스케이프 처리 누락

SQL 문자열 리터럴은 작은따옴표로 감싸이기 때문에, 문자열 내부에 작은따옴표 문자 자체가 포함되어야 할 경우 반드시 두 개의 작은따옴표('')로 이스케이프해야 합니다. 이를 처리하지 않으면 Oracle 파서는 첫 번째 내부 따옴표에서 문자열이 종료된 것으로 판단하고, 이후 문자열을 올바르게 해석하지 못해 ORA-01756을 발생시킵니다. 예를 들어 사람 이름(O’Brien), 가게 이름(McDonald’s) 등 아포스트로피가 포함된 데이터를 직접 SQL에 삽입할 때 흔히 발생합니다.

2. 동적 SQL 또는 애플리케이션 코드에서 따옴표 짝이 맞지 않는 경우

Java, Python, PHP 등 애플리케이션 코드에서 문자열을 연결(concatenation)하여 동적으로 SQL을 생성할 때, 변수 값에 따옴표가 포함되어 있으면 최종적으로 완성되는 SQL 문자열에서 따옴표의 짝이 맞지 않게 됩니다. 이 경우 실제 SQL이 Oracle에 전달되기 전까지 에러를 인지하기 어렵고, 특히 사용자 입력을 그대로 SQL에 삽입하는 방식은 SQL Injection 취약점과도 직결됩니다.

3. 멀티라인 문자열 또는 특수문자 처리 미흡

SQL*Plus, SQL Developer, 또는 스크립트 파일에서 여러 줄에 걸친 문자열 리터럴을 작성할 때 줄바꿈 처리가 잘못되거나, 복사·붙여넣기 과정에서 유니코드 방향성 따옴표(U+2018, U+2019 등 스마트 따옴표)가 일반 ASCII 작은따옴표 대신 삽입되는 경우 ORA-01756이 발생합니다. 특히 Word, 웹 브라우저 등에서 SQL을 복사해 올 때 이러한 문제가 자주 발생하며, 육안으로는 구분이 어렵기 때문에 디버깅이 까다롭습니다.


해결 방법

원인 1 해결: 작은따옴표 이스케이프 처리

잘못된 예:

-- ORA-01756 발생: O'Brien의 내부 따옴표가 문자열을 조기 종료시킴
SELECT * FROM employees WHERE last_name = 'O'Brien';

올바른 예 – 이중 작은따옴표 사용:

-- 작은따옴표를 ''(두 개)로 이스케이프
SELECT * FROM employees WHERE last_name = 'O''Brien';

-- INSERT 예시
INSERT INTO customers (name, address)
VALUES ('McDonald''s', '123 Main St');

Oracle 10g 이상 – q-quote(대체 따옴표) 문법 사용 (권장):

-- q'[...]' 문법으로 내부 따옴표 이스케이프 없이 사용 가능
SELECT * FROM employees WHERE last_name = q'[O'Brien]';

INSERT INTO customers (name, note)
VALUES (q'[McDonald's]', q'[John's favorite store]');

-- 구분자는 [], {}, (), <> 중 선택 가능
SELECT q'{It's a beautiful day}' AS message FROM dual;

원인 2 해결: 동적 SQL에서 바인드 변수 사용

잘못된 예 (문자열 직접 연결):

-- PL/SQL 동적 SQL에서 문자열 직접 연결 시 위험
DECLARE
  v_name VARCHAR2(100) := 'O''Brien'; -- 이미 이스케이프 필요
  v_sql  VARCHAR2(500);
BEGIN
  -- 아래 방식은 SQL Injection 및 ORA-01756 위험
  v_sql := 'SELECT * FROM employees WHERE last_name = ''' || v_name || '''';
  EXECUTE IMMEDIATE v_sql;
END;
/

올바른 예 – 바인드 변수 사용 (강력 권장):

-- EXECUTE IMMEDIATE + USING 절로 바인드 변수 활용
DECLARE
  v_name VARCHAR2(100) := 'O''Brien';
  v_sql  VARCHAR2(500);
  v_count NUMBER;
BEGIN
  v_sql := 'SELECT COUNT(*) FROM employees WHERE last_name = :1';
  EXECUTE IMMEDIATE v_sql INTO v_count USING v_name;
  DBMS_OUTPUT.PUT_LINE('Count: ' || v_count);
END;
/
-- 정적 SQL에서도 바인드 변수 사용 예시 (SQL*Plus / SQLcl)
VARIABLE v_name VARCHAR2(100);
EXEC :v_name := 'O''Brien';

SELECT employee_id, first_name, last_name
FROM   employees
WHERE  last_name = :v_name;

원인 3 해결: 스마트 따옴표 및 멀티라인 문자열 처리

-- 스마트 따옴표 문제 확인: DUMP 함수로 실제 문자 코드 확인
SELECT DUMP('테스트 문자열', 1016) FROM dual;
-- 정상 작은따옴표의 ASCII 코드는 39(16진수 27)여야 함

-- 멀티라인 문자열 올바른 처리 (CLOB 또는 CHR 함수 활용)
INSERT INTO memo_table (content)
VALUES ('첫 번째 줄' || CHR(10) || '두 번째 줄');

-- q-quote 문법으로 멀티라인 처리
INSERT INTO memo_table (content)
VALUES (q'[
이것은 멀티라인
문자열입니다.
작은따옴표(')도 자유롭게 사용 가능합니다.
]');

에러 발생 시 빠른 진단 쿼리

-- 현재 세션에서 마지막 SQL 에러 위치 확인
SELECT * FROM v$sql
WHERE  sql_text LIKE '%employees%'
AND    ROWNUM <= 5
ORDER  BY last_active_time DESC;

-- DBMS_SQL 패키지로 동적 SQL 파싱 전 검증
DECLARE
  v_cursor INTEGER;
  v_sql    VARCHAR2(1000);
BEGIN
  v_sql := 'SELECT * FROM employees WHERE last_name = ''O''''Brien''';
  v_cursor := DBMS_SQL.OPEN_CURSOR;
  BEGIN
    DBMS_SQL.PARSE(v_cursor, v_sql, DBMS_SQL.NATIVE);
    DBMS_OUTPUT.PUT_LINE('SQL 파싱 성공');
  EXCEPTION
    WHEN OTHERS THEN
      DBMS_OUTPUT.PUT_LINE('파싱 실패: ' || SQLERRM);
  END;
  DBMS_SQL.CLOSE_CURSOR(v_cursor);
END;
/

예방 방법

1. 바인드 변수(Bind Variable)를 기본 코딩 표준으로 채택

모든 동적 SQL 및 애플리케이션 코드에서 사용자 입력값이나 변수 값을 SQL 문자열에 직접 연결하는 방식을 금지하고, 반드시 바인드 변수(:변수명 또는 ?)를 통해 값을 전달하는 것을 팀 코딩 표준으로 정립하세요. 이 방법은 ORA-01756 예방은 물론, SQL Injection 방어, 실행 계획 재사용(Soft Parsing)으로 인한 성능 향상, 라이브러리 캐시 효율화까지 동시에 달성할 수 있는 가장 효과적인 베스트 프랙티스입니다.

2. Oracle q-quote 문법(q'[...]') 도입 및 코드 리뷰 체크리스트 적용

Oracle 10g 이상 환경에서는 따옴표가 포함된 문자열 리터럴을 작성할 때 반드시 q-quote 문법을 사용하도록 코딩 가이드라인에 명시하세요. 또한 CI/CD 파이프라인에 SQL 정적 분석 도구(예: SonarQube with Oracle 플러그인, PL/SQL Analyzer)를 통합하여, 따옴표 미처리 패턴이나 동적 SQL 문자열 직접 연결 패턴을 자동으로 감지하고 코드 리뷰 단계에서 차단하는 체계를 구축하면 운영 환경에서의 에러 발생을 효과적으로 예방할 수 있습니다.


관련 에러

  • ORA-00907: missing right parenthesis — 괄호 미닫힘 오류로, 따옴표 문제로 인해 SQL 구조 자체가 깨질 때 함께 발생하는 경우가 있습니다.
  • ORA-00904: invalid identifier — 따옴표가 잘못 처리되어 컬럼명이나 식별자가 문자열에 섞여 들어갈 때 발생할 수 있습니다.
  • ORA-01740: missing double quote in identifier — 큰따옴표로 감싼 식별자(quoted identifier)가 제대로 닫히지 않았을 때 발생하며, ORA-01756의 큰따옴표 버전에 해당합니다.
  • ORA-06550: line X, column Y: PL/SQL: ORA-01756 — PL/SQL 블록 내에서 ORA-01756이 발생할 때 래핑되어 나타나는 에러로, 라인 및 컬럼 번호를 참고하면 문제 위치를 빠르게 특정할 수 있습니다.

DBMS 에러 코드 시리즈

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

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

댓글 남기기