ORA-00904: Ungültige Kennung

81

Ich habe versucht, die folgende Inner Join-Abfrage mithilfe einer Oracle-Datenbank zu schreiben:

 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

Das ergibt den folgenden Fehler:

 INNER JOIN PS_TBL_DEPARTMENT_DETAILS Team ON Team.DEPARTMENT_CODE = Employee.DEPTID
                                              *
ERROR at line 4:
ORA-00904: "TEAM"."DEPARTMENT_CODE": invalid identifier

Die DDL einer Tabelle lautet:

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
quelle
Sind Sie sicher, dass der Spaltenname Department_Code richtig geschrieben ist?
Fabrizio D'Ammassa
Ja, es gibt eine Spalte Department_Code
Navaneethan
6
TL; DR: Verwenden Sie einfache Anführungszeichen ''.
Andrew

Antworten:

126

Ihr Problem sind diese schädlichen doppelten Anführungszeichen.

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>

Mit Oracle SQL können wir den Fall von Datenbankobjektnamen ignorieren, vorausgesetzt, wir erstellen sie entweder mit Namen in Großbuchstaben oder ohne doppelte Anführungszeichen. Wenn wir im Skript gemischte Groß- oder Kleinschreibung verwenden und die Bezeichner in doppelte Anführungszeichen setzen, sind wir dazu verdammt, doppelte Anführungszeichen und die genaue Groß- und Kleinschreibung zu verwenden, wenn wir auf das Objekt oder seine Attribute verweisen:

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

Verwenden Sie in DDL-Skripten keine doppelten Anführungszeichen

(Ich weiß, dass die meisten Codegeneratoren von Drittanbietern dies tun, aber sie sind diszipliniert genug, um alle ihre Objektnamen in UPPER CASE zu setzen.)


Das Gegenteil ist auch der Fall. Wenn wir die Tabelle ohne doppelte Anführungszeichen erstellen ...

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

… Wir können es und seine Spalten in jedem Fall referenzieren, was uns gefällt:

select * from ps_tbl_department_details

… oder

select * from PS_TBL_DEPARTMENT_DETAILS;

… oder

select * from PS_Tbl_Department_Details
where COMAPNY_CODE = 'ORCL'
and cost_center_number = '0980'
APC
quelle
28
Pernicious beschreibt nicht einmal das Ausmaß der Frustration, die Oracle mit diesen nicht standardmäßigen Praktiken verursacht.
Don Scott
13

In meinem Fall trat dieser Fehler auf, weil der Spaltenname in der Tabelle nicht vorhanden war.

Als ich ausgeführt habe "describe tablename " , konnte ich die in der Mapping-Hbm-Datei angegebene Spalte nicht finden.

Nach dem Ändern der Tabelle funktionierte es gut.

Sireesh Yarlagadda
quelle
1
Ein anderer Fall ist das Fehlen der gesamten Tabelle.
Haoyu Chen
4

DEPARTMENT_CODE ist keine Spalte, die in der Tabelle Team vorhanden ist. Überprüfen Sie die DDL der Tabelle, um den richtigen Spaltennamen zu finden.

Datenstau
quelle
1
Spalte ist in Tabelle vorhanden, die ich überprüft habe
Navaneethan
1
Können Sie uns die DDL der Tabelle PS_TBL_DEPARTMENT_DETAILS geben?
Datajam
1
CREATE TABLE "HRMS". "PS_TBL_DEPARTMENT_DETAILS" ("Buchungskreis" VARCHAR2 (255), "Firmenname" VARCHAR2 (255), "Sector_Code" VARCHAR2 (255), "Sector_Name" VARCHAR2 (255), "Business_Un_" ), "Business_Unit_Name" VARCHAR2 (255), "Department_Code" VARCHAR2 (255), "Department_Name" VARCHAR2 (255), "HR_ORG_ID" VARCHAR2 (255), "HR_ORG_Name" VARCHAR2 (255), "Cost_CAR_ "" VARCHAR2 (255)) SEGMENTERSTELLUNG SOFORT PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRES
Navaneethan
4
Wenn dies wirklich die DDL ist, wurden die Spalten so erstellt, dass zwischen Groß- und Kleinschreibung unterschieden wird. Sie sollten die doppelten Anführungszeichen aus den Spaltendefinitionen entfernen. Wenn Sie die Tabelle nicht neu erstellen können, verwenden Sie Team. "Department_Name" in Ihrer select-Anweisung.
Datajam
4
Mir gefällt besonders der Name der letzten Spalte; Irgendwelche Vermutungen, was dort gespeichert wird?
Alex Poole
4

Zu Ihrer Information, in diesem Fall wurde festgestellt, dass die Ursache ein gemischter Fallspaltenname in der DDL für die Tabellenerstellung ist.

Wenn Sie jedoch "Old Style" - und ANSI-Joins mischen, wird möglicherweise dieselbe Fehlermeldung angezeigt, auch wenn die DDL ordnungsgemäß mit dem Namen der Großbuchstabentabelle ausgeführt wurde. Dies ist mir passiert und Google hat mich auf diese Stackoverflow-Seite geschickt, sodass ich dachte, ich würde sie teilen, seit ich hier bin.

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

Die beiden obigen SQL-Anweisungen sind äquivalent und erzeugen keinen Fehler.

Wenn Sie versuchen, sie zu mischen, können Sie Glück haben, oder Sie können ein Oracle mit einem ORA-00904-Fehler erhalten.

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

Und die nicht hilfreiche Fehlermeldung, die das Problem überhaupt nicht wirklich beschreibt:

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

Ich konnte diesbezüglich im folgenden Blog-Beitrag Nachforschungen anstellen:

In meinem Fall habe ich versucht, manuell Joins im alten Stil in ANSI-Style-Joins zu konvertieren, und zwar schrittweise, jeweils eine Tabelle nach der anderen. Dies scheint eine schlechte Idee gewesen zu sein. Stattdessen ist es wahrscheinlich besser, alle Tabellen gleichzeitig zu konvertieren oder eine Tabelle und ihre Where-Bedingungen in der ursprünglichen Abfrage auskommentieren, um sie mit der neuen ANSI-Abfrage zu vergleichen, die Sie schreiben.

qyb2zm302
quelle
2

Sind Sie sicher, dass Ihre Tabelle PS_TBL_DEPARTMENT_DETAILS eine Spalte DEPARTEMENT_CODE enthält ?

Weitere Informationen zu Ihrem FEHLER

ORA-00904: Zeichenfolge: ungültiger Bezeichner Ursache: Der eingegebene Spaltenname fehlt oder ist ungültig. Aktion: Geben Sie einen gültigen Spaltennamen ein. Ein gültiger Spaltenname muss mit einem Buchstaben beginnen, kleiner oder gleich 30 Zeichen sein und nur aus alphanumerischen Zeichen und den Sonderzeichen $, _ und # bestehen. Wenn es andere Zeichen enthält, muss es in doppelte Anführungszeichen gesetzt werden. Es kann kein reserviertes Wort sein.

mcha
quelle
1

Ich hatte diesen Fehler beim Versuch, eine Entität über JPA zu speichern.

Es war, weil ich eine Spalte mit @JoinColumnAnnotation hatte, die keine @ManyToOneAnnotation hatte.

Durch Hinzufügen wurde @ManyToOnedas Problem behoben.

alseddiq
quelle
0

Ich hatte die gleiche Ausnahme in JPA 2 mit Eclipse Link. Ich hatte eine @ eingebettete Klasse mit einer Eins-zu-Eins-Beziehung zu einer Entität. Aus Versehen hatte ich in der eingebetteten Klasse auch die Annotation @Table ("TRADER"). Als die Datenbank von der JPA aus den Entitäten erstellt wurde, wurde auch eine Tabelle TRADER erstellt (was falsch war, da die Trader-Entität in die Hauptentität eingebettet war), und das Vorhandensein dieser Tabelle verursachte bei jedem Versuch die obige Ausnahme beharrt auf meiner Entität. Nach dem Löschen der TRADER-Tabelle verschwand die Ausnahme.

CLS
quelle
0

Stellen Sie außerdem sicher, dass dem Benutzer, der die Abfrage ausstellt, die erforderlichen Berechtigungen erteilt wurden.

Für Abfragen in Tabellen müssen Sie die Berechtigung SELECT erteilen.
Für Abfragen zu anderen Objekttypen (z. B. gespeicherte Prozeduren) müssen Sie die EXECUTE-Berechtigung erteilen.

voccoeisuoi
quelle
0

Ich habe die Werte ohne Anführungszeichen übergeben. Sobald ich die Bedingungen in den einfachen Anführungszeichen erfüllt hatte, wirkte es wie ein Zauber.

Select * from emp_table where emp_id=123;

Verwenden Sie stattdessen Folgendes:

Select * from emp_table where emp_id='123';
Ashutosh
quelle