ORA-00904:无效的标识符


81

我尝试使用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,2011年

6
TL; DR:使用单引号''
安德鲁

Answers:


126

您的问题是那些有害的双引号。

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
有害的甚至没有开始描述Oracle对这些非标准实践造成的沮丧程度。
唐·斯科特

13

在我的情况下,由于表中缺少列名而发生此错误。

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

更改表后,它工作正常。


1
另一种情况是整个表的缺失。
陈浩宇

4

DEPARTMENT_CODE不是表Team中存在的列。检查表的DDL以查找正确的列名。


1
列存在于我检查过的表格中
Navaneethan 2011年

1
您能给我们表PS_TBL_DEPARTMENT_DETAILS的DDL吗?
2011年

1
创建表“ 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))立即创建片段创建10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRES
Navaneethan 2011年

4
如果这确实是DDL,则列已创建为区分大小写。您应该从列定义中删除双引号。如果无法重新创建表,请在select语句中使用Team。“ Department_Name”。
Datajam

4
我特别喜欢最后一列的名称;任何猜测什么存储在那里?
亚历克斯·普尔

4

仅供参考,在这种情况下,发现原因是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
/

上面的两个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样式的连接,并且每次都递增一个表。这似乎是一个坏主意。相反,最好一次转换所有表,或者注释掉表及其原始查询中的where条件,以便与您正在编写的新ANSI查询进行比较。


2

你确定你有一列DEPARTEMENT_CODE你的桌子上PS_TBL_DEPARTMENT_DETAILS

有关您的错误的更多信息

ORA-00904:字符串:无效的标识符原因:输入的列名丢失或无效。行动:输入一个有效的列名。有效的列名称必须以字母开头,且小于或等于30个字符,并且仅由字母数字字符和特殊字符$,_和#组成。如果包含其他字符,则必须将其括在d双引号中。它可能不是保留字。


1

尝试通过JPA保存实体时出现此错误。

这是因为我有一列带有@JoinColumn注释的列而没有@ManyToOne注释。

添加@ManyToOne解决了该问题。


0

我在JPA 2中使用eclipse链接遇到了相同的异常。我有一个与实体一对一关系的@embedded类。错误地,在嵌入式类中,我还有注解@Table(“ TRADER”)。当JPA从实体中创建数据库时,它还创建了一个表TRADER(这是错误的,因为Trader实体已嵌入到主实体中),并且每次我尝试使用该表时,都会导致上述异常坚持我的实体。删除TRADER表后,异常消失了。


0

还要确保发出查询的用户已被授予必要的权限。

对于表查询,您需要授予SELECT权限。
对于其他对象类型(例如存储过程)的查询,您需要授予EXECUTE权限。


0

我传递的值不带引号。一旦我通过了条件,单引号就起了作用。

Select * from emp_table where emp_id=123;

代替上面的使用这个:

Select * from emp_table where emp_id='123';
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.