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 написана правильно?
Фабріціо Д'Аммасса,

Так, є графа Department_Code
Navaneethan

6
TL; DR: використовуйте одинарні лапки ''.
Ендрю,

Відповіді:


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; д-р

не використовуйте подвійні лапки в сценаріях 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
Інший випадок - відсутність усієї таблиці.
Haoyu Chen

5

FYI, у цьому випадку виявлено, що причиною є ім’я стовпця змішаного регістру в 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, який ви пишете.


4

DEPARTMENT_CODE - це не стовпець, який існує в таблиці Team. Перевірте DDL таблиці, щоб знайти правильну назву стовпця.


1
стовпець існує в таблиці, яку я перевірив
Наванетан,

1
Чи можете ви дати нам DDL таблиці PS_TBL_DEPARTMENT_DETAILS?
Datajam

1
СТВОРИТИ ТАБЛИЦЮ "HRMS". "PS_TBL_DEPARTMENT_DETAILS" ("Код компанії" VARCHAR2 (255), "Назва компанії" VARCHAR2 (255), "Sector_Code" VARCHAR2 (255), "Sector_Name" VARCHAR2 (255), "Business_Unit_Code" 255 VARCHAR ), "Business_Unit_Name" VARCHAR2 (255), "Unit_Code" VARCHAR2 (255), "Department_Name" VARCHAR2 (255), "HR_ORG_ID" VARCHAR2 (255), "HR_ORG_Name" VARCHAR2 (255), "Cost_Center_Number" VARCHAR2 (VARCHAR2) "" VARCHAR2 (255)) СТВОРЕННЯ СЕГМЕНТУ НЕЗАБАЖНО PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRES
Navaneethan

4
Якщо це справді DDL, то стовпці були створені з урахуванням регістру. Вам слід видалити подвійні лапки з визначень стовпців. Якщо вам не вдається заново створити таблицю, використовуйте команду "Ім'я_відділу" у вашому операторі вибору.
Datajam

4
Мені особливо подобається назва останнього стовпця; будь-які здогади, що там зберігається?
Алекс Пул,

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';
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.