본문 바로가기

IT/SQL

테이블, 컬럼 있는 거 다 확인 했는데 ORA – 00904: 부적합한 식별자 에러 가 뜰 때

기존 개발 된 페이지 수정 요청을 받아 어떤 페이지인지 보려고 프로젝트를 당겨 받아서 실행 했더니 바로 오류가 났다. 

이상하게 stg 에서는 문제가 없는데 dev 에서는 자꾸 ORA – 00904: 부적합한 식별자 에러가 생겼다. 

 

일단 stg 로 db.properties 를 바꾸고 수정을 끝내고 쿼리가 dev에서만 안 도는 이유를 찾기 시작했다. 

 

나의 가설

1. stg 에서 같은 쿼리문이 문제 없이 돌아가니 문법 문제는 아닌 것 같았다. 또한 쿼리에 있는 테이블과 컬럼명에 문제 없음을 알 수 있었다. 

1-1. DEV 와 STG DB 의 실행 순서가 달라서 생기는 문제가 아닐까 의심했다. 

 

2. 이미지로 첨부한 최신 아이템 명을 들고오는 쿼리를 주석 처리 했을 때 잘 돌아가니 쟤가 문제다. 

(쿼리가 천 줄 가까이 되는데 에러가 나면 일단 서브쿼리 부터 실행 해보고 서브 쿼리가 다 잘 돌아가면

일단 서브쿼리 하나만 살려 놓고 전체 실행 해보고 이런 식으로 대략적인 오류 부분을 찾아나가는 방식을 사용하고 있다)

 

3. 삼중 서브 쿼리에서 맨 안에 있는 쿼리가 문제였고 14번째 줄 JOIN_TABLE.POST_DATE 를 가장 바깥쪽 서브쿼리로 꺼내서 WHERE 절에 적어주면 잘 돌아갔다. 

 

삼중 쿼리의 의도는 아이템 코드에 여러 개의 아이템 명이 저장될 수 있는데,

아이템 명 중에서 가장 최신에 등록된 명을 들고 오려고 한 것이다. 

 

 

오류가 발생했던 이유

 

ITEM_NAME 은 SELECT 절에서 하나의 결과 값만 출력하므로 스칼라 서브 쿼리이다.

 

하지만 스칼라 서브 쿼리 내, 인라인뷰(FROM 절 서브쿼리)에서 최신 아이템 명을 조회하고 있다.

인라인뷰는 독립실행 하므로 인라인뷰 쿼리 안에서 조인 된 쿼리의 컬럼을 가져다 쓰면 디비는 해당 컬럼을 알 수가 없다.

 

해결방법

1.WITH 절 사용
2.KEEP(DENSE_RANK FIRST/LAST) 
=> 오라클 전용 함수는 회사에서 지양하고 있어서 이 방법은 개인적으로만 수정해 보았다. 
3.인덱스 생성 (STG DB 에는 인덱스가 있었다)
4. JOIN으로 바꾸기  
 
개인적으로 4번 방법이 가장 가독성이 좋았다. 

 

인라인뷰는 단독으로 실행이 가능해야 한다는 기본적인 개념을 다시 새길 수 있는 좋은 기회였다.