我尝试使用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
答案 0 :(得分:95)
你的问题是那些有害的双引号。
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脚本中使用双引号
(我知道大多数第三方代码生成器都可以,但是它们足够严格,可以将所有对象名称放在UPPER CASE中。)
答案 1 :(得分:10)
就我而言,由于表中没有列名,因此发生了此错误。
当我执行&#34; describe tablename
&#34; ,我无法找到映射hbm文件中指定的列。
改变表后,它运行良好。
答案 2 :(得分: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样式联接,并且逐步增加,一次一个表。这似乎是个坏主意。相反,最好一次转换所有表,或者注释掉表及其在原始查询中的条件,以便与您正在编写的新ANSI查询进行比较。
答案 3 :(得分:3)
DEPARTMENT_CODE不是表Team中存在的列。检查表的DDL以找到正确的列名。
答案 4 :(得分:1)
您确定桌面上有 DEPARTEMENT_CODE 列 PS_TBL_DEPARTMENT_DETAILS
More informations关于您的错误
ORA-00904:字符串:无效的标识符 原因:输入的列名称丢失或无效。 操作:输入有效的列名称。有效的列名必须以a开头 信件, 小于或等于30个字符,仅由 字母数字字符和 特殊字符$,_和#。 如果它包含其他字符,则必须用d double括起来 引号。 它可能不是一个保留字。
答案 5 :(得分:0)
我在使用eclipse链接的JPA 2中遇到了同样的异常。我有一个与实体有一对一关系的@embedded类。 错误地,在嵌入式类中,我还有注释@Table(“TRADER”)。当JPA从实体创建数据库时,它还创建了一个表TRADER(当Trader实体嵌入到主实体时这是错误的)并且每次我尝试时该表的存在导致上述异常坚持我的实体。 删除TRADER表后,异常消失了。
答案 6 :(得分:0)
还要确保已发出查询的用户已获得必要的权限。
对于表格的查询,您需要授予SELECT权限 对于其他对象类型(例如存储过程)的查询,您需要授予EXECUTE权限。
答案 7 :(得分:0)
我传递的值没有引号。一旦我通过单引号内的条件就像一个魅力。
Select * from emp_table where emp_id=123;
代替以上使用此:
Select * from emp_table where emp_id='123';
答案 8 :(得分:0)
确保DDL语句后没有/。
答案 9 :(得分:0)
我有同样的例外,在我的案例中的问题是由于子查询中不存在该列 - 尽管我知道“缺失”列/标识符属于具有我所指的别名的表。
示例 - 此查询在 MC.SIT_TYPE
列中生成 ORA-00904 - 无效标识符:
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;
这里有一些提示:
答案 10 :(得分: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 年历史...