ORA-00904: ongeldige identificatie

Ik heb geprobeerd de volgende innerlijke joinquery te schrijven met behulp van een Oracle-database:

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

die de onderstaande fout geeft:

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

De DDL van één tabel is:

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

1, Autoriteit 100%

Uw probleem is die pernicieuze dubbele aanhalingstekens.

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 stelt ons in staat om namen van databaseobjecten te negeren, op voorwaarde dat we ze ofwel maken met namen allemaal in hoofdletters, of zonder dubbele aanhalingstekens te gebruiken. Als we hoofdletters of kleine letters gebruiken in het script en de identifiers tussen dubbele aanhalingstekens zetten, zijn we veroordeeld tot het gebruik van dubbele aanhalingstekens en het precieze geval wanneer we naar het object of zijn attributen verwijzen:

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

gebruik geen dubbele aanhalingstekens in DDL-scripts

(Ik weet dat de meeste codegeneratoren van derden dat doen, maar ze zijn gedisciplineerd genoeg om al hun objectnamen in HOOFDLETTERS te zetten.)


Het omgekeerde is ook waar. Als we de tabel maken zonder dubbele aanhalingstekens te gebruiken …

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

… we kunnen ernaar verwijzen en de kolommen ervan in elk geval dat we leuk vinden:

select * from ps_tbl_department_details

… of

select * from PS_TBL_DEPARTMENT_DETAILS;

… of

select * from PS_Tbl_Department_Details
where COMAPNY_CODE = 'ORCL'
and cost_center_number = '0980'

2, Autoriteit 10%

In mijn geval is deze fout opgetreden, vanwege het gebrek aan bestaan ​​van kolomnaam in de tabel.

Wanneer ik “describe tablename“, kreeg ik niet in staat om de kolom te vinden die is opgegeven in het Mapping HBM-bestand.

Na het wijzigen van de tabel, werkte het prima.


3, Autoriteit 4%

FYI, in dit geval bleek de oorzaak gemengde case kolomnaam in de DDL voor het maken van tabel.

Als u echter “oude stijl” mengt en ANSI inhoudt, kunt u hetzelfde foutbericht krijgen, zelfs wanneer de DDL correct is gedaan met hoofdnaam in hoofdletters. Dit gebeurde mij, en Google heeft me naar deze stapelaarspagina gestuurd, dus ik dacht dat ik zou delen sinds ik hier was.

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

De twee SQL-uitspraken hierboven zijn equivalent en produceren geen fout.

Als je ze probeert te mixen, kun je geluk hebben, of je kunt een Oracle krijgen met een ORA-00904-fout.

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

En de nutteloze foutmelding die het probleem helemaal niet beschrijft:

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

Ik heb hier wat onderzoek naar kunnen vinden in de volgende blogpost:

In mijn geval probeerde ik handmatig joins in oude stijl om te zetten in ANSI-stijl, en deed ik dit stapsgewijs, tabel voor tabel. Dit blijkt een slecht idee te zijn geweest. In plaats daarvan is het waarschijnlijk beter om alle tabellen in één keer te converteren, of een tabel en zijn waar-voorwaarden in de oorspronkelijke query uit commentaar te geven om te vergelijken met de nieuwe ANSI-query die u aan het schrijven bent.


Antwoord 4, autoriteit 3%

DEPARTMENT_CODE is geen kolom die voorkomt in de tabel Team. Controleer de DDL van de tabel om de juiste kolomnaam te vinden.


Antwoord 5, autoriteit 2%

Weet u zeker dat u een kolom DEPARTEMENT_CODEin uw tabel heeft PS_TBL_DEPARTMENT_DETAILS

Meer informatieover uw FOUT

ORA-00904: string: ongeldige identifier
Oorzaak: De ingevoerde kolomnaam ontbreekt of is ongeldig.
Actie: Voer een geldige kolomnaam in. Een geldige kolomnaam moet beginnen met a
brief,
kleiner zijn dan of gelijk zijn aan 30 tekens, en bestaan uit alleen
alfanumerieke tekens en
de speciale tekens $, _ en #.
Als het andere tekens bevat, moet het worden ingesloten in d double
aanhalingstekens.
Het is misschien geen gereserveerd woord.


Antwoord 6, autoriteit 2%

Ik kreeg deze fout bij het opslaan van een entiteit via JPA.

Het was omdat ik een kolom had met de annotatie @JoinColumndie geen annotatie @ManyToOnehad.

Het toevoegen van @ManyToOneloste het probleem op.


Antwoord 7

Ik had dezelfde uitzondering in JPA 2 met de eclipse-link. Ik had een @embedded-klas met een één-op-één relatie met een entiteit.
Per ongeluk had ik in de ingesloten klasse ook de annotatie @Table (“TRADER”). Toen de DB door de JPA van de entiteiten werd gemaakt, creëerde het ook een tabel TRADER (wat een fout was omdat de entiteit Trader was ingebed in de hoofdentiteit) en het bestaan van die tabel veroorzaakte de bovenstaande uitzondering elke keer dat ik probeerde om volhard mijn entiteit.
Na het verwijderen van de TRADER-tabel verdween de uitzondering.


Antwoord 8

Zorg er ook voor dat de gebruiker die de query uitvoert, de benodigde machtigingen heeft gekregen.

Voor query’s op tabellen moet u SELECT-machtiging verlenen.
Voor query’s op andere objecttypen (bijv. opgeslagen procedures) moet u EXECUTE-toestemming verlenen.


Antwoord 9

Ik gaf de waarden door zonder de aanhalingstekens. Toen ik eenmaal geslaagd was voor de voorwaarden binnen de enkele aanhalingstekens, werkte het als een charme.

Select * from emp_table where emp_id=123;

gebruik in plaats van het bovenstaande dit:

Select * from emp_table where emp_id='123';

Other episodes