web-dev-qa-db-ja.com

ORA-00904:無効な識別子

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

以下のエラーが発生します。

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

1つのテーブルのDDLは次のとおりです。

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
56
Navaneethan

あなたの問題は、それらの有害な二重引用符です。

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では、名前をすべて大文字で作成するか、二重引用符を使用せずに作成すると、データベース・オブジェクト名の大文字と小文字を無視できます。スクリプトで大文字と小文字を混ぜて使用し、識別子を二重引用符で囲むと、オブジェクトまたはその属性を参照するときは常に二重引用符と正確な大文字小文字を使用することになります。

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

dDLスクリプトで二重引用符を使用しないでください

(ほとんどのサードパーティのコードジェネレーターが行うことを知っていますが、それらはすべてのオブジェクト名を大文字に入れるのに十分な規律があります。)

95
APC

私の場合、テーブルに列名が存在しないため、このエラーが発生しました。

"describe tablename"を実行したときに、マッピングhbmファイルで指定された列を見つけることができませんでした。

テーブルを変更した後、正常に機能しました。

10

参考までに、この場合、原因はテーブル作成用のDDLで大文字と小文字が混在する列名であることが判明しました。

ただし、「古いスタイル」とANSI結合を混在させると、大文字のテーブル名でDDLが適切に実行された場合でも、同じエラーメッセージが表示される可能性があります。これは私に起こり、グーグルはこのstackoverflowページに私を送ったので、私はここにいたので共有したいと思った。

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

上記の2つのSQLステートメントは同等であり、エラーは発生しません。

それらをミックスしようとすると、ラッキーになるか、Oracleに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
/

そして、問題をまったく説明していない役に立たないエラーメッセージ:

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

次のブログ投稿でこれに関するいくつかの研究を見つけることができました。

私の場合、古いスタイルからANSIスタイルの結合に手動で変換しようとしており、一度に1つのテーブルずつ増分的に変換していました。これは悪い考えだったようです。代わりに、作成中の新しいANSIクエリと比較するために、すべてのテーブルを一度に変換するか、テーブルと元のクエリのwhere条件をコメント化する方がおそらく良いでしょう。

4
qyb2zm302

DEPARTMENT_CODEは、テーブルTeamに存在する列ではありません。テーブルのDDLを確認して、適切な列名を見つけてください。

3
Datajam

テーブルに列DEPARTEMENT_CODEがありますか?PS_TBL_DEPARTMENT_DETAILS

詳細 エラーについて

ORA-00904:文字列:無効な識別子原因:入力された列名が欠落しているか無効です。処置:有効な列名を入力してください。有効な列名は文字で始まり、30文字以下で、英数字と特殊文字$、_、および#のみで構成されている必要があります。他の文字が含まれている場合は、d二重引用符で囲む必要があります。予約語ではない場合があります。

1
mcha

また、クエリを発行するユーザーに必要な権限が付与されていることを確認してください。

テーブルのクエリでは、SELECT権限を付与する必要があります。
他のオブジェクトタイプ(ストアドプロシージャなど)のクエリでは、EXECUTE権限を付与する必要があります。

0
voccoeisuoi

JPAを介してエンティティを保存しようとすると、このエラーが発生しました。

それは、@JoinColumn注釈のない@ManyToOne注釈の列があったためです。

@ManyToOneを追加すると、問題が修正されました。

0
alseddiq

Eclipseリンクを使用したJPA 2でも同じ例外がありました。エンティティと1対1の関係を持つ@embeddedクラスがありました。誤って、組み込みクラスでは、アノテーション@Table( "TRADER")もありました。 DBがエンティティからJPAによって作成されたときに、TRADERテーブルも作成しました(トレーダーエンティティがメインエンティティに埋め込まれたため間違っていました)。エンティティを永続化します。 TRADERテーブルを削除した後、例外は消滅しました。

0
Pitelk

DDLステートメントの後に/がないことを確認してください。

0
Rakesh

引用符なしで値を渡していました。一重引用符内の条件を渡すと、魅力のように機能しました。

Select * from emp_table where emp_id=123;

上記の代わりにこれを使用してください:

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