ORA-00904: nieprawidłowy identyfikator

84

Próbowałem napisać następujące zapytanie sprzężenia wewnętrznego przy użyciu bazy danych 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

To daje poniższy błąd:

 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 jednej tabeli to:

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
Navaneethan
źródło
Czy na pewno nazwa kolumny Department_Code jest wpisana poprawnie?
Fabrizio D'Ammassa
Tak, jest kolumna Department_Code
Navaneethan
6
TL; DR: użyj apostrofów ''.
Andrew

Odpowiedzi:

128

Twoim problemem są te zgubne podwójne cytaty.

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 pozwala nam ignorować wielkość liter w nazwach obiektów bazy danych, pod warunkiem, że utworzymy je z nazwami pisanymi wielkimi literami lub bez cudzysłowów. Jeśli w skrypcie używamy małych lub małych liter i opakowujemy identyfikatory w podwójne cudzysłowy, jesteśmy skazani na używanie podwójnych cudzysłowów i dokładnych wielkości liter, gdy odnosimy się do obiektu lub jego atrybutów:

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

nie używaj podwójnych cudzysłowów w skryptach DDL

(Wiem, że większość zewnętrznych generatorów kodu to robi, ale są wystarczająco zdyscyplinowani, aby umieścić wszystkie nazwy obiektów WIELKIMI LITERAMI).


Odwrotna jest również prawda. Jeśli utworzymy tabelę bez użycia cudzysłowów…

create table PS_TBL_DEPARTMENT_DETAILS
( company_code VARCHAR2(255),
  company_name VARCHAR2(255),
  Cost_Center_Number VARCHAR2(255))
;

… Możemy odwołać się do niego i jego kolumn w dowolnym przypadku:

select * from ps_tbl_department_details

… Lub

select * from PS_TBL_DEPARTMENT_DETAILS;

… Lub

select * from PS_Tbl_Department_Details
where COMAPNY_CODE = 'ORCL'
and cost_center_number = '0980'
APC
źródło
28
Szkodliwe nawet nie zaczyna opisywać poziomu frustracji powodowanej przez Oracle tymi niestandardowymi praktykami.
Don Scott,
13

W moim przypadku ten błąd wystąpił z powodu braku nazwy kolumny w tabeli.

Kiedy describe tablenamewykonałem „ ”, nie mogłem znaleźć kolumny określonej w pliku mapowania HBM.

Po przeróbce stołu działało dobrze.

Sireesh Yarlagadda
źródło
1
Innym przypadkiem jest brak całego stołu.
Haoyu Chen
5

FYI, w tym przypadku przyczyną była mieszana nazwa kolumny wielkości liter w DDL do tworzenia tabeli.

Jednakże, jeśli mieszasz "stary styl" i łączenia ANSI, możesz otrzymać ten sam komunikat o błędzie, nawet jeśli DDL został wykonany poprawnie z nazwą tabeli wielkimi literami. Przydarzyło mi się to i Google wysłało mnie na tę stronę stackoverflow, więc pomyślałem, że udostępnię to, odkąd tu byłem.

--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
/

Dwie powyższe instrukcje SQL są równoważne i nie powodują błędów.

Kiedy próbujesz je mieszać, możesz mieć szczęście lub możesz uzyskać błąd ORA-00904 w Oracle.

--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
/

I nieprzydatny komunikat o błędzie, który w ogóle nie opisuje problemu:

>[Error] Script lines: 1-12 -------------------------
ORA-00904: "A"."EMPLID": invalid identifier  Script line 6, statement line 6,
column 51 

Kilka badań na ten temat udało mi się znaleźć w następującym wpisie na blogu:

W moim przypadku próbowałem ręcznie przekonwertować ze starego stylu na złączenia typu ANSI i robiłem to stopniowo, po jednej tabeli na raz. Wygląda na to, że to zły pomysł. Zamiast tego prawdopodobnie lepiej jest przekonwertować wszystkie tabele naraz lub zakomentować tabelę i jej warunki w pierwotnym zapytaniu, aby porównać ją z nowym piszonym zapytaniem ANSI.

qyb2zm302
źródło
4

DEPARTMENT_CODE nie jest kolumną, która istnieje w tabeli Zespół. Sprawdź DDL tabeli, aby znaleźć właściwą nazwę kolumny.

Datajam
źródło
1
kolumna istnieje w tabeli, którą
zaznaczyłem
1
Czy możesz podać nam DDL tabeli PS_TBL_DEPARTMENT_DETAILS?
Datajam
1
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 ), „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 "" VARCHAR2 (255)) TWORZENIE SEGMENTU NATYCHMIAST PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRES
Navaneethan
4
Jeśli to naprawdę jest DDL, wówczas kolumny zostały utworzone z uwzględnieniem wielkości liter. Należy usunąć podwójne cudzysłowy z definicji kolumn. Jeśli nie możesz ponownie utworzyć tabeli, użyj Zespołu. „Nazwa_ działu” w instrukcji Select.
Datajam
4
Szczególnie podoba mi się nazwa ostatniej kolumny; zgadniesz, co jest tam przechowywane?
Alex Poole
2

Czy na pewno masz kolumnę DEPARTEMENT_CODE w swojej tabeli PS_TBL_DEPARTMENT_DETAILS

Więcej informacji o Twoim błędzie

ORA-00904: string: nieprawidłowy identyfikator Przyczyna: Brak wprowadzonej nazwy kolumny lub jest ona nieprawidłowa. Akcja: wprowadź prawidłową nazwę kolumny. Prawidłowa nazwa kolumny musi zaczynać się od litery, mieć co najmniej 30 znaków i składać się wyłącznie ze znaków alfanumerycznych oraz znaków specjalnych $, _ i #. Jeśli zawiera inne znaki, musi być ujęty w podwójne cudzysłowy. To nie może być słowo zastrzeżone.

mcha
źródło
1

Wystąpił ten błąd podczas próby zapisania jednostki przez JPA.

To dlatego, że miałem kolumnę z @JoinColumnadnotacją, która nie miała @ManyToOneadnotacji.

Dodanie @ManyToOnerozwiązało problem.

alseddiq
źródło
0

Miałem ten sam wyjątek w JPA 2 przy użyciu łącza zaćmienia. Miałem klasę @embedded z relacją jeden do jednego z jednostką. Przez pomyłkę w klasie osadzonej miałem również adnotację @Table („TRADER”). Kiedy baza danych została utworzona przez JPA z podmiotów, utworzyła również tabelę PODMIOTÓW (co było błędem, ponieważ jednostka Tradera została osadzona w jednostce głównej), a istnienie tej tabeli powodowało powyższy wyjątek za każdym razem, gdy próbowałem trwać w mojej istocie. Po usunięciu tabeli TRADER wyjątek zniknął.

CLS
źródło
0

Upewnij się również, że użytkownik wysyłający zapytanie ma niezbędne uprawnienia.

W przypadku zapytań dotyczących tabel musisz nadać uprawnienie SELECT.
W przypadku zapytań dotyczących innych typów obiektów (np. Procedur składowanych) musisz nadać uprawnienie EXECUTE.

voccoeisuoi
źródło
0

Podałem wartości bez cudzysłowów. Kiedy spełniłem warunki wewnątrz, pojedyncze cudzysłowy działały jak urok.

Select * from emp_table where emp_id=123;

zamiast powyższego użyj tego:

Select * from emp_table where emp_id='123';
Ashutosh
źródło