95

我尝试使用 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
4

12 回答 12

140

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

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;博士

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

(我知道大多数第三方代码生成器都会这样做,但他们有足够的纪律性,可以将所有对象名称都放在大写字母中。)


反之亦然。如果我们在不使用双引号的情况下创建表……</p>

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'
于 2011-05-17T11:59:18.397 回答
13

就我而言,由于表中不存在列名,因此发生了此错误。

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

改变表后,它工作正常。

于 2014-05-06T16:32:06.933 回答
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
/

上面的两条 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 查询进行比较。

于 2013-10-08T02:12:53.087 回答
4

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

于 2011-05-17T08:24:38.403 回答
2

你确定你的表 PS_TBL_DEPARTMENT_DETAILS 上有列DEPARTEMENT_CODE

有关您的错误的更多信息

ORA-00904:字符串:无效的标识符原因:输入的列名丢失或无效。行动:输入一个有效的列名。有效的列名必须以字母开头,少于或等于 30 个字符,并且仅包含字母数字字符和特殊字符 $、_ 和 #。如果它包含其他字符,那么它必须用 d 双引号引起来。它可能不是保留字。

于 2011-05-17T08:16:39.120 回答
2

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

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

添加@ManyToOne解决了这个问题。

于 2019-03-12T17:54:27.643 回答
0

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

于 2013-01-24T10:45:39.020 回答
0

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

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

于 2016-07-14T09:45:41.520 回答
0

在我的情况下,错误是由于对列名使用错误的大小写引起的,而且您似乎遇到了同样的问题。

Department_CodeDEPARTMENT_CODEOracle 不同。

于 2021-11-18T07:25:39.403 回答
0

我收到了错误消息,因为我错过了一个表别名并且没有使用。

由于 'cl' 别名,这会引发错误:

SELECT * FROM MYSCHEMA.COMPANYLOCATION_CL cl JOIN MYSCHEMA.COMPANYTYPE_CT ON MYSCHEMA.COMPANYLOCATION_CL.CLNR = MYSCHEMA.COMPANYTYPE_CT.CT_CL_NR 

没有'cl'它工作正常:

SELECT * FROM MYSCHEMA.COMPANYLOCATION_CL JOIN MYSCHEMA.COMPANYTYPE_CT ON MYSCHEMA.COMPANYLOCATION_CL.CLNR = MYSCHEMA.COMPANYTYPE_CT.CT_CL_NR 

请不要抱怨表名 - 架构已有 20 年历史......

于 2021-08-09T15:30:28.477 回答
0

我传递的值没有引号。一旦我通过了单引号内的条件,就像一个魅力。

Select * from emp_table where emp_id=123;

而不是上面的使用这个:

Select * from emp_table where emp_id='123';
于 2016-10-24T09:05:17.480 回答
0

我有同样的例外,我的问题是由于子查询中不存在该列 - 尽管我知道“缺失”列/标识符属于我所指的别名的表。

示例 -此查询在列生成ORA-00904 - 无效标识符MC.SIT_TYPE

SELECT MC.ID_CODE,
       MC.EMP_NAME
FROM (SELECT MC.ID_CODE, 
             MC.EMP_NAME
      FROM EMP_WORKER MC) MC
INNER JOIN TEM_SHEETS FR ON MC.SIT_TYPE = FR.ID_CODE -- This line has the ORA-00904 error.
LEFT JOIN WRK_TYPE RAS ON MC.ID_CODE = RAS.ID_CODE;

现在,在修改子查询后 - 通过添加MC.SIT_TYPE列 - ,ORA-00904消失。

结果:

SELECT MC.ID_CODE,
       MC.EMP_NAME
FROM (SELECT MC.ID_CODE, 
             MC.EMP_NAME, ​
            ​ -- Here, the "missing invalid identifier, in this case (MC.SIT_TYPE)" is added: 
             MC.SIT_TYPE
      FROM EMP_WORKER MC) MC
INNER JOIN TEM_SHEETS FR ON MC.SIT_TYPE = FR.ID_CODE 
LEFT JOIN WRK_TYPE RAS ON MC.ID_CODE = RAS.ID_CODE;

以下是一些提示:

  • 非常仔细地检查代码的制表/缩进 - (取决于您的设置),SQL Developer 处理代码的缩进不同。
  • 您正在处理的代码可能没有制表/缩进 - 使这类错误的调试更加困难和耗时。
  • 修改列/子查询的别名——一般代码——用于生成唯一别名——我的意思是:不要对子查询和相关表使用相同的别名。
于 2021-04-22T15:06:12.217 回答