ORA-00904:无效的标识符

Nav*_*han 64 sql database oracle ora-00904

我尝试使用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
Run Code Online (Sandbox Code Playgroud)

这给出了以下错误:

 INNER JOIN PS_TBL_DEPARTMENT_DETAILS Team ON Team.DEPARTMENT_CODE = Employee.DEPTID
                                              *
ERROR at line 4:
ORA-00904: "TEAM"."DEPARTMENT_CODE": invalid identifier
Run Code Online (Sandbox Code Playgroud)

一个表的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
Run Code Online (Sandbox Code Playgroud)

APC*_*APC 105

你的问题是那些有害的双引号.

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>
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)

TL;博士

不要在DDL脚本中使用双引号

(我知道大多数第三方代码生成器都可以,但是它们足够严格,可以将所有对象名称放在UPPER CASE中.)

  • Pernicious甚至没有开始描述Oracle对这些非标准做法造成的挫败感. (18认同)
  • 甲骨文很糟糕。可怕的计划。 (3认同)

Sir*_*dda 11

在我的情况下,由于表中没有列名,因此发生了此错误.

当我执行" describe tablename"时,我无法找到映射hbm文件中指定的列.

改变表后,它工作正常.


qyb*_*302 5

仅供参考,在这种情况下,发现原因是 DDL 中用于表创建的列名混合大小写。

但是,如果您混合使用“旧样式”和 ANSI 连接,即使 DDL 使用大写表名正确完成,您也可能会收到相同的错误消息。这发生在我身上,谷歌将我发送到这个 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
/
Run Code Online (Sandbox Code Playgroud)

上面两条 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
/
Run Code Online (Sandbox Code Playgroud)

以及根本没有真正描述问题的无用错误消息:

>[Error] Script lines: 1-12 -------------------------
ORA-00904: "A"."EMPLID": invalid identifier  Script line 6, statement line 6,
column 51 
Run Code Online (Sandbox Code Playgroud)

我能够在以下博客文章中找到一些关于此的研究:

就我而言,我试图手动从旧样式转换为 ANSI 样式连接,并且以增量方式进行,一次一个表。这似乎是一个坏主意。相反,最好一次转换所有表,或者在原始查询中注释掉一个表及其 where 条件,以便与您正在编写的新 ANSI 查询进行比较。