2026년 07월 29일 | DBMS Error 가이드
이 글에서 다루는 내용
ORA-01747 에러의 원인 분석, 해결 SQL, 예방 방법을 실무 관점에서 정리합니다.
ORA-01747 invalid user.table.column specification 는?
ORA-01747 에러는 Oracle SQL 문에서 컬럼 명세(user.table.column 또는 table.column 형식)가 올바르지 않을 때 발생하는 에러입니다. 주로 UPDATE 문의 SET 절이나 INSERT 문에서 컬럼명을 잘못 지정하거나, 예약어(Reserved Word)를 컬럼명으로 사용했을 때 Oracle 파서가 해당 구문을 인식하지 못하면서 발생합니다. 30년간 현장에서 보아온 경험상, 이 에러는 대부분 개발자의 단순 실수나 SQL 문법 오해에서 비롯되므로 원인을 빠르게 파악하면 쉽게 해결할 수 있습니다.
주요 발생 원인
1. UPDATE SET 절에서 테이블 별칭(Alias) 또는 테이블명을 컬럼 앞에 붙인 경우
Oracle의 UPDATE 문 SET 절에서는 컬럼명 앞에 테이블명이나 별칭을 붙일 수 없습니다. 이는 Oracle SQL의 문법적 제약으로, 많은 개발자들이 SELECT 문의 습관대로 테이블.컬럼 = 값 형식을 사용하다가 이 에러를 만나게 됩니다. 특히 다른 DBMS(MySQL, SQL Server 등)에서 Oracle로 마이그레이션하는 과정에서 자주 발생하는 실수입니다.
2. 예약어(Reserved Word)를 컬럼명으로 사용한 경우
Oracle은 DATE, LEVEL, COMMENT, NUMBER, TABLE, SELECT 등 수백 개의 예약어를 가지고 있습니다. 이러한 예약어를 테이블 컬럼명으로 사용하게 되면, SQL 파서가 해당 단어를 컬럼명이 아닌 키워드로 인식하여 구문 분석에 실패하고 ORA-01747 에러를 발생시킵니다. 레거시 시스템을 유지보수하거나 다른 DBMS에서 스키마를 이전할 때 특히 주의가 필요합니다.
3. 컬럼 명세에 특수문자, 공백, 또는 잘못된 구분자가 포함된 경우
컬럼명이나 테이블명에 공백, 하이픈(-), 슬래시(/) 등의 특수문자가 포함된 경우, 올바른 큰따옴표(") 처리를 하지 않으면 SQL 파서가 컬럼 명세를 올바르게 해석하지 못합니다. 또한 user.table.column 구문에서 점(.) 대신 다른 문자를 구분자로 사용하거나 점의 위치가 잘못된 경우에도 이 에러가 발생합니다. 시스템 연동이나 동적 SQL 생성 시 특히 주의가 필요한 케이스입니다.
해결 방법
원인 1 해결: UPDATE SET 절에서 테이블 별칭 제거
잘못된 예시:
-- 오류 발생: SET 절에서 테이블명(별칭) 사용
UPDATE employees e
SET e.salary = e.salary * 1.1,
e.last_modified = SYSDATE
WHERE e.department_id = 10;
올바른 수정 예시:
-- 정상 동작: SET 절에서 컬럼명만 사용
UPDATE employees e
SET salary = salary * 1.1,
last_modified = SYSDATE
WHERE e.department_id = 10;
서브쿼리를 이용한 UPDATE도 마찬가지입니다:
-- 오류 발생: 서브쿼리 UPDATE에서 잘못된 컬럼 명세
UPDATE (SELECT e.salary, e.department_id FROM employees e)
SET e.salary = 5000
WHERE e.department_id = 20;
-- 정상 동작
UPDATE (SELECT salary, department_id FROM employees)
SET salary = 5000
WHERE department_id = 20;
원인 2 해결: 예약어 컬럼명을 큰따옴표로 감싸기
-- 예약어가 컬럼명으로 사용된 테이블 생성 예시 (비권장)
CREATE TABLE order_info (
order_id NUMBER,
"DATE" DATE, -- 예약어 DATE를 큰따옴표로 처리
"COMMENT" VARCHAR2(200) -- 예약어 COMMENT를 큰따옴표로 처리
);
-- 예약어 컬럼 조회 시 큰따옴표 필수
SELECT order_id, "DATE", "COMMENT"
FROM order_info
WHERE "DATE" >= TRUNC(SYSDATE);
-- 예약어 컬럼 UPDATE 시
UPDATE order_info
SET "COMMENT" = '배송 완료',
"DATE" = SYSDATE
WHERE order_id = 1001;
예약어 여부를 확인하는 쿼리:
-- 특정 단어가 Oracle 예약어인지 확인
SELECT keyword, reserved
FROM v$reserved_words
WHERE keyword = 'DATE'
OR keyword = 'COMMENT'
OR keyword = 'LEVEL'
ORDER BY keyword;
-- 현재 테이블의 컬럼명이 예약어와 겹치는지 사전 점검
SELECT c.column_name, r.reserved
FROM user_tab_columns c
JOIN v$reserved_words r ON c.column_name = r.keyword
WHERE c.table_name = 'ORDER_INFO';
원인 3 해결: 특수문자가 포함된 컬럼명 처리
-- 특수문자/공백이 포함된 컬럼명 생성 시 (가급적 피할 것)
CREATE TABLE product_info (
product_id NUMBER,
"product name" VARCHAR2(100), -- 공백 포함
"unit-price" NUMBER(10,2) -- 하이픈 포함
);
-- 반드시 큰따옴표와 정확한 대소문자로 참조
INSERT INTO product_info (product_id, "product name", "unit-price")
VALUES (1, 'Oracle Database', 999.99);
SELECT product_id,
"product name",
"unit-price"
FROM product_info
WHERE "unit-price" > 500;
-- 동적 SQL 생성 시 컬럼명 검증 예시 (PL/SQL)
DECLARE
v_sql VARCHAR2(4000);
v_col_name VARCHAR2(128) := 'salary';
v_table VARCHAR2(128) := 'employees';
v_value NUMBER := 6000;
BEGIN
-- 컬럼명에 특수문자가 없는지 간단 검증
IF REGEXP_LIKE(v_col_name, '^[A-Za-z][A-Za-z0-9_$#]*$') THEN
v_sql := 'UPDATE ' || v_table ||
' SET ' || v_col_name || ' = :1' ||
' WHERE employee_id = :2';
EXECUTE IMMEDIATE v_sql USING v_value, 100;
COMMIT;
DBMS_OUTPUT.PUT_LINE('업데이트 성공');
ELSE
DBMS_OUTPUT.PUT_LINE('유효하지 않은 컬럼명: ' || v_col_name);
END IF;
END;
/
예방 방법
1. 테이블 및 컬럼 명명 규칙(Naming Convention) 수립 및 준수
팀 또는 조직 차원에서 명명 규칙을 수립하고, Oracle 예약어 목록을 사전에 검토하여 컬럼명이나 테이블명으로 사용하지 않도록 강제하는 것이 중요합니다. 예를 들어 DATE 대신 ORDER_DATE, REG_DATE처럼 의미를 명확히 하는 접두사 또는 접미사를 붙이는 규칙을 도입하면 예약어 충돌을 원천적으로 방지할 수 있습니다. DDL 스크립트를 코드 리뷰하는 프로세스를 도입하고, 아래와 같은 스크립트로 신규 컬럼명을 사전 검증하는 습관을 들이세요.
-- 신규 컬럼명이 예약어인지 사전 검증하는 쿼리
SELECT keyword, reserved
FROM v$reserved_words
WHERE keyword = UPPER('&new_column_name');
-- 결과가 있으면 해당 이름 사용 금지
2. SQL 작성 시 IDE의 문법 검사 기능 적극 활용 및 코드 리뷰 의무화
SQL Developer, Toad, DBeaver 등 주요 Oracle 개발 도구는 실시간 문법 오류 감지 기능을 제공합니다. UPDATE 문의 SET 절에서 테이블명/별칭을 붙이는 실수는 이러한 도구의 구문 강조(Syntax Highlighting) 및 경고 기능으로 사전에 잡아낼 수 있습니다. 또한 운영 DB에 직접 실행하기 전, 반드시 개발/스테이징 환경에서 SQL을 테스트하고 팀원 코드 리뷰를 거치는 프로세스를 의무화하는 것을 강력히 권장합니다.
관련 에러
- ORA-00904:
invalid identifier— 존재하지 않는 컬럼명이나 잘못된 식별자를 사용했을 때 발생. ORA-01747과 유사한 상황에서 함께 등장하는 경우가 많음. - ORA-00923:
FROM keyword not found where expected— SELECT 문 구조가 잘못되었을 때 발생하며, 컬럼 명세 오류와 함께 발생하는 경우가 있음. - ORA-00936:
missing expression— UPDATE SET 절이나 WHERE 절에서 표현식이 누락되거나 잘못된 경우 발생하며, 컬럼 명세 오류와 연쇄적으로 발생하기도 함. - ORA-01745:
invalid host/bind variable name— 바인드 변수명이 잘못 지정된 경우로, 동적 SQL에서 ORA-01747과 함께 발생할 수 있음.
주요 DBMS error code를 정리하는 시리즈입니다.
블로그 홈에서 다른 에러도 확인하세요.
본 포스트는 AI가 생성한 기술 가이드입니다. 운영 환경 적용 전 충분한 검토를 권장합니다.