ORA-00904: identificador no válido

82

Intenté escribir la siguiente consulta de unión interna usando una base de datos de 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

Eso da el siguiente error:

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

El DDL de una tabla es:

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
fuente
¿Está seguro de que el nombre de la columna Department_Code está escrito correctamente?
Fabrizio D'Ammassa
Sí, hay una columna Department_Code
Navaneethan
6
TL; DR: use comillas simples ''.
Andrew

Respuestas:

127

Tu problema son esas perniciosas comillas dobles.

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 nos permite ignorar las mayúsculas y minúsculas de los nombres de los objetos de la base de datos siempre que los creemos con nombres en mayúsculas o sin usar comillas dobles. Si usamos mayúsculas o minúsculas en el script y envolvemos los identificadores entre comillas dobles estamos condenados a usar comillas dobles y el caso preciso siempre que nos referimos al objeto o sus atributos:

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

no use comillas dobles en los scripts DDL

(Sé que la mayoría de los generadores de código de terceros lo hacen, pero son lo suficientemente disciplinados como para poner todos los nombres de sus objetos en MAYÚSCULAS).


Lo contrario también es cierto. Si creamos la tabla sin usar comillas dobles ...

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

... podemos hacer referencia a él y sus columnas en cualquier caso que nos apetezca:

select * from ps_tbl_department_details

… O

select * from PS_TBL_DEPARTMENT_DETAILS;

… O

select * from PS_Tbl_Department_Details
where COMAPNY_CODE = 'ORCL'
and cost_center_number = '0980'
APC
fuente
28
Pernicious ni siquiera comienza a describir el nivel de frustración que causa Oracle con estas prácticas no estándar.
Don Scott
13

En mi caso, este error ocurrió debido a la falta de existencia del nombre de la columna en la tabla.

Cuando ejecuté " describe tablename", no pude encontrar la columna especificada en el archivo hbm de mapeo.

Después de alterar la tabla, funcionó bien.

Sireesh Yarlagadda
fuente
1
Otro caso es la falta de toda la mesa.
Haoyu Chen
4

DEPARTMENT_CODE no es una columna que exista en la tabla Equipo. Verifique el DDL de la tabla para encontrar el nombre de columna adecuado.

Datajam
fuente
1
La columna existe en la tabla que verifiqué
Navaneethan
1
¿Puede darnos el DDL de la tabla PS_TBL_DEPARTMENT_DETAILS?
Datajam
1
CREAR TABLA "HRMS". "PS_TBL_DEPARTMENT_DETAILS" ("Código de empresa" VARCHAR2 (255), "Nombre de empresa" 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)) CREACIÓN DE SEGMENTO INMEDIATA PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRES
Navaneethan
4
Si ese es realmente el DDL, entonces las columnas se han creado para distinguir entre mayúsculas y minúsculas. Debe eliminar las comillas dobles de las definiciones de columna. Si no puede volver a crear la tabla, use Team. "Department_Name" en su declaración de selección.
Datajam
4
Me gusta especialmente el nombre de la última columna; ¿Alguna suposición de lo que se almacena allí?
Alex Poole
4

Para su información, en este caso se encontró que la causa era un nombre de columna de caso mixto en el DDL para la creación de la tabla.

Sin embargo, si está mezclando "estilo antiguo" y combinaciones ANSI, podría obtener el mismo mensaje de error incluso cuando el DDL se realizó correctamente con el nombre de la tabla en mayúsculas. Esto me pasó a mí, y Google me envió a esta página de stackoverflow, así que pensé en compartir desde que estaba aquí.

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

Las dos declaraciones SQL anteriores son equivalentes y no producen ningún error.

Cuando intentas mezclarlos, puedes tener suerte, o puedes obtener un error de Oracle con 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
/

Y el mensaje de error inútil que realmente no describe el problema en absoluto:

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

Pude encontrar algo de investigación sobre esto en la siguiente publicación del blog:

En mi caso, estaba intentando convertir manualmente de un estilo antiguo a uniones de estilo ANSI, y lo estaba haciendo de forma incremental, una tabla a la vez. Esto parece haber sido una mala idea. En cambio, probablemente sea mejor convertir todas las tablas a la vez, o comentar una tabla y sus condiciones en la consulta original para compararla con la nueva consulta ANSI que está escribiendo.

qyb2zm302
fuente
2

¿Está seguro de que tiene una columna DEPARTEMENT_CODE en su tabla? PS_TBL_DEPARTMENT_DETAILS

Más información sobre tu ERROR

ORA-00904: cadena: identificador no válido Causa: Falta el nombre de la columna o no es válido. Acción: ingrese un nombre de columna válido. Un nombre de columna válido debe comenzar con una letra, ser menor o igual a 30 caracteres y constar únicamente de caracteres alfanuméricos y los caracteres especiales $, _ y #. Si contiene otros caracteres, debe estar entre comillas dobles d. Puede que no sea una palabra reservada.

mcha
fuente
1

Tuve este error al intentar guardar una entidad a través de JPA.

Fue porque tenía una columna con una @JoinColumnanotación que no tenía@ManyToOne anotación.

Agregar @ManyToOnesolucionó el problema.

alseddiq
fuente
0

Tuve la misma excepción en JPA 2 usando el enlace eclipse. Tenía una clase @embedded con una relación uno a uno con una entidad. Por error, en la clase incrustada, también tenía la anotación @Table ("TRADER"). Cuando JPA creó la base de datos a partir de las entidades, también creó una tabla TRADER (lo cual era incorrecto ya que la entidad Trader estaba incrustada en la entidad principal) y la existencia de esa tabla estaba causando la excepción anterior cada vez que intentaba persiste mi entidad. Después de eliminar la tabla TRADER, la excepción desapareció.

CLS
fuente
0

También asegúrese de que el usuario que realiza la consulta tenga los permisos necesarios.

Para consultas sobre tablas, debe otorgar el permiso SELECT.
Para consultas sobre otros tipos de objetos (por ejemplo, procedimientos almacenados), debe otorgar el permiso EXECUTE.

voccoeisuoi
fuente
0

Estaba pasando los valores sin las comillas. Una vez que pasé las condiciones dentro de las comillas simples funcionó a las mil maravillas.

Select * from emp_table where emp_id=123;

en lugar de lo anterior usa esto:

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