ORA-00904: số nhận dạng không hợp lệ


81

Tôi đã cố gắng viết truy vấn nối bên trong sau bằng cơ sở dữ liệu 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

Điều đó gây ra lỗi dưới đây:

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

DDL của một bảng là:

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

Bạn có chắc chắn tên cột Mã Cục được viết đúng chính tả không?
Fabrizio D'Ammassa

Có, có một cột Department_Code
Navaneethan

6
TL; DR: sử dụng dấu ngoặc kép ''.
Andrew

Câu trả lời:


126

Vấn đề của bạn là những dấu ngoặc kép độc hại.

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 cho phép chúng ta bỏ qua trường hợp tên đối tượng cơ sở dữ liệu miễn là chúng ta tạo chúng với tên tất cả đều là chữ hoa hoặc không sử dụng dấu ngoặc kép. Nếu chúng tôi sử dụng chữ hoa và chữ thường hỗn hợp trong tập lệnh và bao bọc các số nhận dạng trong dấu ngoặc kép, chúng tôi bị quy kết là sử dụng dấu ngoặc kép và trường hợp chính xác bất cứ khi nào chúng tôi tham chiếu đến đối tượng hoặc các thuộc tính của nó:

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

không sử dụng dấu ngoặc kép trong tập lệnh DDL

(Tôi biết hầu hết các trình tạo mã của bên thứ ba đều làm vậy, nhưng họ đủ kỷ luật để đặt tất cả các tên đối tượng của mình trong TRƯỜNG HỢP LÊN.)


Điều ngược lại cũng đúng. Nếu chúng ta tạo bảng mà không sử dụng dấu ngoặc kép…

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

… Chúng ta có thể tham chiếu nó và các cột của nó trong mọi trường hợp khiến chúng ta ưa thích:

select * from ps_tbl_department_details

… hoặc là

select * from PS_TBL_DEPARTMENT_DETAILS;

… hoặc là

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

28
Pernicious thậm chí không bắt đầu mô tả mức độ thất vọng mà Oracle gây ra với những hoạt động không chuẩn này.
Don Scott

13

Trong trường hợp của tôi, lỗi này xảy ra do thiếu tên cột trong bảng.

Khi tôi thực thi " describe tablename", tôi không thể tìm thấy cột được chỉ định trong tệp ánh xạ hbm.

Sau khi thay đổi bảng, nó hoạt động tốt.


1
Một trường hợp khác là thiếu cả bảng.
Haoyu Chen

4

DEPARTMENT_CODE không phải là một cột tồn tại trong Nhóm bảng. Kiểm tra DDL của bảng để tìm tên cột thích hợp.


1
cột tồn tại trong bảng tôi đã kiểm tra
Navaneethan

1
Bạn có thể cung cấp cho chúng tôi DDL của bảng PS_TBL_DEPARTMENT_DETAILS không?
Datajam

1
TẠO BẢNG "HRMS". "PS_TBL_DEPARTMENT_DETAILS" ("Mã công ty" VARCHAR2 (255), "Tên công ty" VARCHAR2 (255), "Mã ngành" VARCHAR2 (255), "Tên ngành" VARCHAR2 (255), "Mã doanh nghiệp" 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)) TẠO PHÂN ĐOẠN NGAY LẬP TỨC PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRES
Navaneethan

4
Nếu đó thực sự là DDL, thì các cột đã được tạo phân biệt chữ hoa chữ thường. Bạn nên xóa dấu ngoặc kép khỏi định nghĩa cột. Nếu bạn không thể tạo lại bảng, hãy sử dụng Team. "Department_Name" trong tuyên bố đã chọn của bạn.
Datajam

4
Tôi đặc biệt thích tên cột cuối cùng; bất kỳ đoán những gì được lưu trữ trong đó?
Alex Poole,

4

FYI, trong trường hợp này, nguyên nhân được tìm thấy là tên cột chữ hoa chữ thường hỗn hợp trong DDL để tạo bảng.

Tuy nhiên, nếu bạn đang trộn "kiểu cũ" và tham gia ANSI, bạn có thể nhận được thông báo lỗi tương tự ngay cả khi DDL được thực hiện đúng với tên bảng viết hoa. Điều này đã xảy ra với tôi và google đã đưa tôi đến trang stackoverflow này nên tôi nghĩ rằng tôi sẽ chia sẻ kể từ khi tôi ở đây.

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

Hai câu lệnh SQL ở trên là tương đương và không có lỗi.

Khi bạn cố gắng kết hợp chúng, bạn có thể gặp may, hoặc bạn có thể nhận được Oracle có lỗi 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
/

Và thông báo lỗi vô ích không thực sự mô tả sự cố:

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

Tôi có thể tìm thấy một số nghiên cứu về điều này trong bài đăng trên blog sau:

Trong trường hợp của tôi, tôi đã cố gắng chuyển đổi thủ công từ kiểu cũ sang các phép nối kiểu ANSI và đang làm như vậy từng bước, từng bảng một. Đây dường như là một ý tưởng tồi. Thay vào đó, có lẽ tốt hơn là chuyển đổi tất cả các bảng cùng một lúc hoặc nhận xét một bảng và các điều kiện của nó trong truy vấn ban đầu để so sánh với truy vấn ANSI mới mà bạn đang viết.


2

Bạn có chắc mình có cột DEPARTEMENT_CODE trên bảng PS_TBL_DEPARTMENT_DETAILS của mình không

Thêm thông tin về LỖI của bạn

ORA-00904: string: mã định danh không hợp lệ Nguyên nhân: Tên cột đã nhập bị thiếu hoặc không hợp lệ. Hành động: Nhập tên cột hợp lệ. Tên cột hợp lệ phải bắt đầu bằng một chữ cái, nhỏ hơn hoặc bằng 30 ký tự và chỉ bao gồm các ký tự chữ và số và các ký tự đặc biệt $, _ và #. Nếu nó chứa các ký tự khác thì nó phải được đặt trong d dấu ngoặc kép. Nó có thể không phải là một từ dành riêng.


1

Tôi đã gặp lỗi này khi cố gắng lưu một thực thể thông qua JPA.

Đó là vì tôi có một cột có @JoinColumnchú thích mà không có @ManyToOnechú thích.

Thêm đã @ManyToOnekhắc phục sự cố.


0

Tôi đã có ngoại lệ tương tự trong JPA 2 bằng cách sử dụng liên kết nhật thực. Tôi đã có một lớp @embedded với mối quan hệ 1-1 với một thực thể. Do nhầm lẫn, trong lớp nhúng, tôi cũng có chú thích @Table ("TRADER"). Khi DB được tạo bởi JPA từ các thực thể, nó cũng tạo ra một TRADER bảng (điều này là sai khi thực thể Trader được nhúng vào thực thể chính) và sự tồn tại của bảng đó đã gây ra ngoại lệ trên mỗi khi tôi cố gắng kiên trì thực thể của tôi. Sau khi xóa bảng TRADER, ngoại lệ đã biến mất.


0

Đồng thời đảm bảo rằng người dùng phát hành truy vấn đã được cấp các quyền cần thiết.

Đối với các truy vấn trên bảng, bạn cần cấp quyền CHỌN.
Đối với các truy vấn trên các kiểu đối tượng khác (ví dụ: các thủ tục được lưu trữ), bạn cần cấp quyền THỰC HIỆN.


0

Tôi đã chuyển các giá trị mà không có dấu ngoặc kép. Một khi tôi vượt qua các điều kiện bên trong các dấu ngoặc kép đơn lẻ, nó hoạt động như một cái duyên.

Select * from emp_table where emp_id=123;

thay vì ở trên sử dụng cái này:

Select * from emp_table where emp_id='123';
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.