ORA-00904: неверный идентификатор - PullRequest
59 голосов
/ 17 мая 2011

Я попытался написать следующий запрос внутреннего соединения с использованием базы данных 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

Ответы [ 9 ]

95 голосов
/ 17 мая 2011

Ваша проблема в этих пагубных двойных кавычках.

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'
10 голосов
/ 06 мая 2014

В моем случае эта ошибка произошла из-за отсутствия имени столбца в таблице.

Когда я выполнил "describe tablename", я не смог найти столбец, указанный в файле отображения hbm.

После изменения таблицы все заработало нормально.

4 голосов
/ 08 октября 2013

К вашему сведению, в этом случае причина была найдена как имя столбца смешанного регистра в DDL для создания таблицы.

Однако, если вы смешиваете «старый стиль» и объединения ANSI, вы можете получить одно и то же сообщение об ошибке, даже если DDL был выполнен правильно с именем таблицы в верхнем регистре. Это случилось со мной, и Google отправил меня на эту страницу переполнения стека, поэтому я решил поделиться, так как был здесь.

--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 голосов
/ 17 мая 2011

DEPARTMENT_CODE - это не столбец, который существует в таблице Team.Проверьте DDL таблицы, чтобы найти правильное имя столбца.

1 голос
/ 17 мая 2011

Вы уверены, что на вашем столе есть столбец DEPARTEMENT_CODE PS_TBL_DEPARTMENT_DETAILS

Дополнительная информация о вашей ОШИБКЕ

ORA-00904: строка: неверный идентификатор Причина: введенное имя столбца отсутствует или неверно.Действие: введите правильное имя столбца.Допустимое имя столбца должно начинаться с буквы, должно быть не более 30 символов и состоять только из буквенно-цифровых символов и специальных символов $, _ и #.Если он содержит другие символы, он должен быть заключен в двойные кавычки.Это не может быть зарезервированным словом.

0 голосов
/ 12 марта 2019

У меня была эта ошибка при попытке сохранить сущность через JPA.

Это потому, что у меня был столбец с аннотацией @JoinColumn, в котором не было аннотации @ManyToOne.

Добавление @ManyToOne исправило проблему.

0 голосов
/ 24 октября 2016

Я передавал значения без кавычек. Однажды я прошел условия внутри одинарных кавычек, которые работали как шарм.

Select * from emp_table where emp_id=123;

вместо вышеуказанного используйте это:

Select * from emp_table where emp_id='123';
0 голосов
/ 14 июля 2016

Также убедитесь, что пользователю, отправляющему запрос, предоставлены необходимые разрешения.

Для запросов к таблицам необходимо предоставить разрешение SELECT.
Для запросов других типов объектов (например, хранимых процедур) вынеобходимо предоставить разрешение EXECUTE.

0 голосов
/ 24 января 2013

У меня было то же исключение в JPA 2 с использованием ссылки затмения.У меня был класс @embedded с отношениями один к одному с сущностью.По ошибке во встроенном классе у меня также была аннотация @Table ("TRADER").Когда БД был создан JPA из сущностей, он также создал таблицу TRADER (что было неправильно, поскольку сущность Trader была встроена в основную сущность), и существование этой таблицы вызывало вышеуказанное исключение каждый раз, когда я пыталсясохраняй мою сущность.После удаления таблицы TRADER исключение исчезло.

...