wake-up-neo.com

ORA-00904: ungültiger Bezeichner

Ich habe versucht, die folgende Inner Join-Abfrage mit 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 gibt 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
53
Navaneethan

Ihr Problem sind diese verderblichen 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>

Oracle SQL erlaubt es uns, die Namen von Datenbankobjekten zu ignorieren, vorausgesetzt, wir erstellen sie entweder mit Namen in Großbuchstaben oder ohne Anführungszeichen. Wenn wir im Skript gemischte Groß- oder Kleinschreibung verwenden und die Bezeichner in doppelte Anführungszeichen setzen, werden wir dazu verdammt, doppelte Anführungszeichen und den genauen Fall 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 keine Anführungszeichen in DDL-Skripts

(Ich kenne die meisten Drittanbieter-Codegeneratoren, aber sie sind diszipliniert genug, um alle ihre Objektnamen in UPPER CASE zu setzen.)

92
APC

In meinem Fall trat dieser Fehler auf, da in der Tabelle kein Spaltenname vorhanden war.

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

Nachdem der Tisch geändert wurde, funktionierte er einwandfrei.

10

Zu Ihrer Information, in diesem Fall wurde in der DDL für die Tabellenerstellung der Name der Spalte mit gemischter Groß-/Kleinschreibung gefunden.

Wenn Sie jedoch "old style" und ANSI-Joins mischen, erhalten Sie möglicherweise dieselbe Fehlermeldung, selbst wenn die DDL ordnungsgemäß mit dem Tabellennamen in Großbuchstaben ausgeführt wurde. Dies ist mir passiert, und Google hat mich zu dieser Stackoverflow-Seite geschickt. Ich dachte, ich würde es 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 gleichwertig und erzeugen keinen Fehler.

Wenn Sie versuchen, sie zu mischen, können Sie Glück haben, oder Sie erhalten einen Oracle-Fehler mit 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
/

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

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

Im folgenden Blogbeitrag konnte ich dazu etwas recherchieren:

In meinem Fall habe ich versucht, manuell von alten Verknüpfungen in ANSI-Verknüpfungen zu konvertieren, und zwar schrittweise, jeweils eine Tabelle. Dies scheint eine schlechte Idee gewesen zu sein. Stattdessen ist es wahrscheinlich besser, alle Tabellen auf einmal zu konvertieren oder eine Tabelle und ihre Where-Bedingungen in der ursprünglichen Abfrage auszukommentieren, um sie mit der neuen ANSI-Abfrage zu vergleichen, die Sie schreiben.

3
qyb2zm302

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.

3
Datajam

Sind Sie sicher, dass Sie eine Spalte DEPARTEMENT_CODE in Ihrer Tabelle PS_TBL_DEPARTMENT_DETAILS haben 

Weitere Informationen über Ihren FEHLER

ORA-00904: Zeichenfolge: ungültiger Bezeichner Ursache: Der eingegebene Spaltenname fehlt oder ist ungültig. Maßnahme: Geben Sie einen gültigen Spaltennamen ein. Ein gültiger Spaltenname muss mit einem .__ beginnen. Brief, kleiner oder gleich 30 Zeichen sein und nur aus .__ bestehen. alphanumerische Zeichen und die Sonderzeichen $, _ und # . Wenn es andere Zeichen enthält, muss es in d double .__ eingeschlossen werden. Anführungszeichen. Es darf kein reserviertes Wort sein.

1
mcha

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

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

0
voccoeisuoi

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

Das lag daran, dass ich eine Spalte mit @JoinColumn-Annotation hatte, die keine @ManyToOne-Annotation hatte.

Das Hinzufügen von @ManyToOne hat das Problem behoben.

0
alseddiq

Ich hatte die gleiche Ausnahme in JPA 2 mit Eclipse-Link. Ich hatte eine @embedded-Klasse mit einer 1: 1-Beziehung zu einer Entität. .__ Ich hatte in der eingebetteten Klasse versehentlich die Annotation @Table ("TRADER"). Als die DB von der JPA aus den Entitäten erstellt wurde, erstellte sie auch eine Tabelle TRADER (was falsch war, da die Entität Trader in die Hauptentität eingebettet war), und das Vorhandensein dieser Tabelle verursachte bei jedem Versuch die obige Ausnahme bleibe mein Wesen Nach dem Löschen der Tabelle TRADER verschwand die Ausnahme.

0
Pitelk

Stellen Sie sicher, dass keine/nach Ihren DDL-Anweisungen vorhanden sind.

0
Rakesh

Ich habe die Werte ohne Anführungszeichen übergeben. Nachdem ich die Bedingungen in den einzelnen Zitaten durchlaufen hatte, funktionierten sie wie ein Zauber. 

Select * from emp_table where emp_id=123;

anstelle der obigen verwenden Sie Folgendes: 

Select * from emp_table where emp_id='123';
0
Ashutosh Singh