ORA-00904 : 잘못된 식별자


84

Oracle 데이터베이스를 사용하여 다음 내부 조인 쿼리를 작성하려고했습니다.

 SELECT Employee.EMPLID as EmpID, 
        Employee.FIRST_NAME AS Name,
        Team.DEPARTMENT_CODE AS TeamID, 
        Team.Department_Name AS teamname
 FROM PS_TBL_EMPLOYEE_DETAILS Employee
 INNER JOIN PS_TBL_DEPARTMENT_DETAILS Team 
 ON Team.DEPARTMENT_CODE = Employee.DEPTID

다음과 같은 오류가 발생합니다.

 INNER JOIN PS_TBL_DEPARTMENT_DETAILS Team ON Team.DEPARTMENT_CODE = Employee.DEPTID
                                              *
ERROR at line 4:
ORA-00904: "TEAM"."DEPARTMENT_CODE": invalid identifier

한 테이블의 DDL은 다음과 같습니다.

CREATE TABLE "HRMS"."PS_TBL_DEPARTMENT_DETAILS"
(
  "Company Code" VARCHAR2(255),
  "Company Name" VARCHAR2(255),
  "Sector_Code" VARCHAR2(255),
  "Sector_Name" VARCHAR2(255),
  "Business_Unit_Code" VARCHAR2(255),
  "Business_Unit_Name" VARCHAR2(255),
  "Department_Code" VARCHAR2(255),
  "Department_Name" VARCHAR2(255),
  "HR_ORG_ID" VARCHAR2(255),
  "HR_ORG_Name" VARCHAR2(255),
  "Cost_Center_Number" VARCHAR2(255),
  " " VARCHAR2(255)
)
SEGMENT CREATION IMMEDIATE PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS

열 이름 Department_Code의 철자가 정확합니까?
Fabrizio D' Ammassa

예 열 Department_Code이있다
Navaneethan

6
요약 : 작은 따옴표를 사용합니다 ''.
Andrew

답변:


128

당신의 문제는 그 악성 큰 따옴표입니다.

SQL> CREATE TABLE "APC"."PS_TBL_DEPARTMENT_DETAILS"
  2  (
  3    "Company Code" VARCHAR2(255),
  4    "Company Name" VARCHAR2(255),
  5    "Sector_Code" VARCHAR2(255),
  6    "Sector_Name" VARCHAR2(255),
  7    "Business_Unit_Code" VARCHAR2(255),
  8    "Business_Unit_Name" VARCHAR2(255),
  9    "Department_Code" VARCHAR2(255),
 10    "Department_Name" VARCHAR2(255),
 11    "HR_ORG_ID" VARCHAR2(255),
 12    "HR_ORG_Name" VARCHAR2(255),
 13    "Cost_Center_Number" VARCHAR2(255),
 14    " " VARCHAR2(255)
 15  )
 16  /

Table created.

SQL>

Oracle SQL을 사용하면 데이터베이스 개체 이름의 대소 문자를 모두 대문자로 작성하거나 큰 따옴표를 사용하지 않고 작성할 수 있습니다. 스크립트에서 대 / 소문자를 혼합하고 식별자를 큰 따옴표로 묶으면 개체 나 그 속성을 참조 할 때마다 큰 따옴표와 정확한 대소 문자를 사용하는 것으로 비난받습니다.

SQL> select count(*) from PS_TBL_DEPARTMENT_DETAILS
  2  where Department_Code = 'BAH'
  3  /
where Department_Code = 'BAH'
      *
ERROR at line 2:
ORA-00904: "DEPARTMENT_CODE": invalid identifier


SQL> select count(*) from PS_TBL_DEPARTMENT_DETAILS
  2  where "Department_Code" = 'BAH'
  3  /

  COUNT(*)
----------
         0

SQL>

tl; dr

DDL 스크립트에서 큰 따옴표를 사용하지 마십시오.

(대부분의 타사 코드 생성기가 수행하는 것을 알고 있지만 모든 개체 이름을 대문자로 입력 할 수있을만큼 훈련되어 있습니다.)


그 반대도 마찬가지입니다. 큰 따옴표를 사용하지 않고 테이블을 생성하면…

create table PS_TBL_DEPARTMENT_DETAILS
( company_code VARCHAR2(255),
  company_name VARCHAR2(255),
  Cost_Center_Number VARCHAR2(255))
;

… 어떤 경우 에든이 정보와 열을 참조 할 수 있습니다.

select * from ps_tbl_department_details

… 또는

select * from PS_TBL_DEPARTMENT_DETAILS;

… 또는

select * from PS_Tbl_Department_Details
where COMAPNY_CODE = 'ORCL'
and cost_center_number = '0980'

28
Pernicious는 이러한 비표준 관행으로 인해 오라클이 야기하는 좌절의 수준을 설명하기 시작하지도 않습니다.
Don Scott

13

제 경우에는 테이블에 열 이름이 없기 때문에이 오류가 발생했습니다.

" describe tablename" 실행했을 때 매핑 hbm 파일에 지정된 열을 찾을 수 없습니다.

테이블을 변경 한 후 정상적으로 작동했습니다.


1
또 다른 경우는 전체 테이블이 누락 된 경우입니다.
Haoyu Chen

5

참고로,이 경우 원인은 테이블 생성을위한 DDL에서 대소 문자가 혼합 된 열 이름 인 것으로 확인되었습니다.

그러나 "이전 스타일"과 ANSI 조인을 혼합하는 경우 DDL이 대문자 테이블 이름으로 제대로 수행 된 경우에도 동일한 오류 메시지가 표시 될 수 있습니다. 이 일이 저에게 일어 났고 Google이 저를이 stackoverflow 페이지로 보냈기 때문에 제가 여기있을 때부터 공유 할 것이라고 생각했습니다.

--NO PROBLEM: ANSI syntax
SELECT A.EMPLID, B.FIRST_NAME, C.LAST_NAME
FROM PS_PERSON A
INNER JOIN PS_NAME_PWD_VW B ON B.EMPLID = A.EMPLID
INNER JOIN PS_HCR_PERSON_NM_I C ON C.EMPLID = A.EMPLID
WHERE 
    LENGTH(A.EMPLID) = 9
    AND LENGTH(B.LAST_NAME) > 5
    AND LENGTH(C.LAST_NAME) > 5
ORDER BY 1, 2, 3
/

--NO PROBLEM: OLD STYLE/deprecated/traditional oracle proprietary join syntax
SELECT A.EMPLID, B.FIRST_NAME, C.LAST_NAME
FROM PS_PERSON A
, PS_NAME_PWD_VW B 
, PS_HCR_PERSON_NM_I C 
WHERE 
    B.EMPLID = A.EMPLID
    and C.EMPLID = A.EMPLID
    and LENGTH(A.EMPLID) = 9
    AND LENGTH(B.LAST_NAME) > 5
    AND LENGTH(C.LAST_NAME) > 5
ORDER BY 1, 2, 3
/

위의 두 SQL 문은 동일하며 오류가 발생하지 않습니다.

혼합하려고하면 운이 좋거나 Oracle에 ORA-00904 오류가 발생할 수 있습니다.

--LUCKY: mixed syntax (ANSI joins appear before OLD STYLE)
SELECT A.EMPLID, B.FIRST_NAME, C.LAST_NAME
FROM 
    PS_PERSON A
    inner join PS_HCR_PERSON_NM_I C on C.EMPLID = A.EMPLID
    , PS_NAME_PWD_VW B
WHERE 
    B.EMPLID = A.EMPLID
    and LENGTH(A.EMPLID) = 9
    AND LENGTH(B.FIRST_NAME) > 5
    AND LENGTH(C.LAST_NAME) > 5
/

--PROBLEM: mixed syntax (OLD STYLE joins appear before ANSI)
--http://sqlfascination.com/2013/08/17/oracle-ansi-vs-old-style-joins/
SELECT A.EMPLID, B.FIRST_NAME, C.LAST_NAME
FROM 
    PS_PERSON A
    , PS_NAME_PWD_VW B
    inner join PS_HCR_PERSON_NM_I C on C.EMPLID = A.EMPLID
WHERE 
    B.EMPLID = A.EMPLID
    and LENGTH(A.EMPLID) = 9
    AND LENGTH(B.FIRST_NAME) > 5
    AND LENGTH(C.LAST_NAME) > 5
/

그리고 문제를 전혀 설명하지 않는 도움이되지 않는 오류 메시지 :

>[Error] Script lines: 1-12 -------------------------
ORA-00904: "A"."EMPLID": invalid identifier  Script line 6, statement line 6,
column 51 

다음 블로그 게시물에서 이에 대한 연구를 찾을 수있었습니다.

제 경우에는 이전 스타일에서 ANSI 스타일 조인으로 수동으로 변환하려고 시도했고 한 번에 하나의 테이블 씩 점진적으로 수행했습니다. 이것은 나쁜 생각 인 것 같습니다. 대신 모든 테이블을 한 번에 변환하거나 작성중인 새 ANSI 쿼리와 비교하기 위해 원래 쿼리에서 테이블과 테이블의 where 조건을 주석 처리하는 것이 좋습니다.


4

DEPARTMENT_CODE는 Team 테이블에있는 열이 아닙니다. 적절한 열 이름을 찾으려면 테이블의 DDL을 확인하십시오.


1
열이 나는 검사 테이블에 존재입니다
Navaneethan

1
PS_TBL_DEPARTMENT_DETAILS 테이블의 DDL을 알려 주실 수 있습니까?
Datajam

1
CREATE TABLE "HRMS". "PS_TBL_DEPARTMENT_DETAILS"( "회사 코드"VARCHAR2 (255), "회사 이름"VARCHAR2 (255), "Sector_Code"VARCHAR2 (255), "Sector_Name"VARCHAR2 (255), "Business_Unit_Code"VARCHAR2 (255) ), "Business_Unit_Name"VARCHAR2 (255), "Department_Code"VARCHAR2 (255), "Department_Name"VARCHAR2 (255), "HR_ORG_ID"VARCHAR2 (255), "HR_ORG_Name"VARCHAR2 (255), "Cost_Center_Number"VARCHAR2 (255), ""VARCHAR2 (255)) 세그먼트 생성 즉시 PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRES
Navaneethan

4
이것이 실제로 DDL이라면 열은 대소 문자를 구분하여 생성되었습니다. 열 정의에서 큰 따옴표를 제거해야합니다. 테이블을 다시 만들 수없는 경우 select 문에서 Team. "Department_Name"을 사용합니다.
Datajam

4
나는 특히 마지막 열 이름을 좋아합니다. 거기에 무엇이 저장되는지 짐작하십니까?
Alex Poole

2

PS_TBL_DEPARTMENT_DETAILS 테이블에 DEPARTEMENT_CODE 열이 있습니까?

ERROR에 대한 추가 정보

ORA-00904 : 문자열 : 유효하지 않은 식별자 원인 : 입력 된 열 이름이 누락되었거나 유효하지 않습니다. 조치 : 유효한 열 이름을 입력하십시오. 유효한 열 이름은 문자로 시작하고 30 자 이하 여야하며 영숫자 문자와 특수 문자 $, _ 및 #으로 만 ​​구성되어야합니다. 다른 문자가 포함 된 경우 d 큰 따옴표로 묶어야합니다. 예약어가 아닐 수 있습니다.


1

JPA를 통해 엔티티를 저장하려고 할 때이 오류가 발생했습니다.

@JoinColumn주석이없는 주석 이있는 열이 있었기 때문 @ManyToOne입니다.

추가 @ManyToOne하면 문제가 해결되었습니다.


0

이클립스 링크를 사용하여 JPA 2에서 동일한 예외가 발생했습니다. 엔터티와 일대일 관계가있는 @embedded 클래스가 있습니다. 실수로 임베디드 클래스에서 @Table ( "TRADER") 주석도있었습니다. DB가 엔티티에서 JPA에 의해 생성되었을 때 테이블 TRADER (Trader 엔티티가 기본 엔티티에 포함 되었기 때문에 잘못됨)도 생성했으며 해당 테이블의 존재로 인해 위의 예외가 발생했습니다. 내 엔티티를 유지하십시오. TRADER 테이블을 삭제 한 후 예외가 사라졌습니다.


0

또한 쿼리를 실행하는 사용자에게 필요한 권한이 부여되었는지 확인하십시오.

테이블에 대한 쿼리의 경우 SELECT 권한을 부여해야합니다.
다른 개체 유형 (예 : 저장 프로 시저)에 대한 쿼리의 경우 EXECUTE 권한을 부여해야합니다.


0

따옴표없이 값을 전달했습니다. 일단 작은 따옴표 안의 조건을 통과하면 매력처럼 작동했습니다.

Select * from emp_table where emp_id=123;

위의 대신 다음을 사용하십시오.

Select * from emp_table where emp_id='123';
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.