Próbowałem napisać następujące zapytanie sprzężenia wewnętrznego przy użyciu bazy danych 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
To daje poniższy błąd:
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 jednej tabeli to:
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
''
.Odpowiedzi:
Twoim problemem są te zgubne podwójne cytaty.
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 pozwala nam ignorować wielkość liter w nazwach obiektów bazy danych, pod warunkiem, że utworzymy je z nazwami pisanymi wielkimi literami lub bez cudzysłowów. Jeśli w skrypcie używamy małych lub małych liter i opakowujemy identyfikatory w podwójne cudzysłowy, jesteśmy skazani na używanie podwójnych cudzysłowów i dokładnych wielkości liter, gdy odnosimy się do obiektu lub jego atrybutów:
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
nie używaj podwójnych cudzysłowów w skryptach DDL
(Wiem, że większość zewnętrznych generatorów kodu to robi, ale są wystarczająco zdyscyplinowani, aby umieścić wszystkie nazwy obiektów WIELKIMI LITERAMI).
Odwrotna jest również prawda. Jeśli utworzymy tabelę bez użycia cudzysłowów…
create table PS_TBL_DEPARTMENT_DETAILS ( company_code VARCHAR2(255), company_name VARCHAR2(255), Cost_Center_Number VARCHAR2(255)) ;
… Możemy odwołać się do niego i jego kolumn w dowolnym przypadku:
select * from ps_tbl_department_details
… Lub
select * from PS_TBL_DEPARTMENT_DETAILS;
… Lub
select * from PS_Tbl_Department_Details where COMAPNY_CODE = 'ORCL' and cost_center_number = '0980'
źródło
W moim przypadku ten błąd wystąpił z powodu braku nazwy kolumny w tabeli.
Kiedy
describe tablename
wykonałem „ ”, nie mogłem znaleźć kolumny określonej w pliku mapowania HBM.Po przeróbce stołu działało dobrze.
źródło
FYI, w tym przypadku przyczyną była mieszana nazwa kolumny wielkości liter w DDL do tworzenia tabeli.
Jednakże, jeśli mieszasz "stary styl" i łączenia ANSI, możesz otrzymać ten sam komunikat o błędzie, nawet jeśli DDL został wykonany poprawnie z nazwą tabeli wielkimi literami. Przydarzyło mi się to i Google wysłało mnie na tę stronę stackoverflow, więc pomyślałem, że udostępnię to, odkąd tu byłem.
--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 /
Dwie powyższe instrukcje SQL są równoważne i nie powodują błędów.
Kiedy próbujesz je mieszać, możesz mieć szczęście lub możesz uzyskać błąd ORA-00904 w Oracle.
--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 /
I nieprzydatny komunikat o błędzie, który w ogóle nie opisuje problemu:
>[Error] Script lines: 1-12 ------------------------- ORA-00904: "A"."EMPLID": invalid identifier Script line 6, statement line 6, column 51
Kilka badań na ten temat udało mi się znaleźć w następującym wpisie na blogu:
W moim przypadku próbowałem ręcznie przekonwertować ze starego stylu na złączenia typu ANSI i robiłem to stopniowo, po jednej tabeli na raz. Wygląda na to, że to zły pomysł. Zamiast tego prawdopodobnie lepiej jest przekonwertować wszystkie tabele naraz lub zakomentować tabelę i jej warunki w pierwotnym zapytaniu, aby porównać ją z nowym piszonym zapytaniem ANSI.
źródło
DEPARTMENT_CODE nie jest kolumną, która istnieje w tabeli Zespół. Sprawdź DDL tabeli, aby znaleźć właściwą nazwę kolumny.
źródło
Czy na pewno masz kolumnę DEPARTEMENT_CODE w swojej tabeli PS_TBL_DEPARTMENT_DETAILS
Więcej informacji o Twoim błędzie
źródło
Wystąpił ten błąd podczas próby zapisania jednostki przez JPA.
To dlatego, że miałem kolumnę z
@JoinColumn
adnotacją, która nie miała@ManyToOne
adnotacji.Dodanie
@ManyToOne
rozwiązało problem.źródło
Miałem ten sam wyjątek w JPA 2 przy użyciu łącza zaćmienia. Miałem klasę @embedded z relacją jeden do jednego z jednostką. Przez pomyłkę w klasie osadzonej miałem również adnotację @Table („TRADER”). Kiedy baza danych została utworzona przez JPA z podmiotów, utworzyła również tabelę PODMIOTÓW (co było błędem, ponieważ jednostka Tradera została osadzona w jednostce głównej), a istnienie tej tabeli powodowało powyższy wyjątek za każdym razem, gdy próbowałem trwać w mojej istocie. Po usunięciu tabeli TRADER wyjątek zniknął.
źródło
Upewnij się również, że użytkownik wysyłający zapytanie ma niezbędne uprawnienia.
W przypadku zapytań dotyczących tabel musisz nadać uprawnienie SELECT.
W przypadku zapytań dotyczących innych typów obiektów (np. Procedur składowanych) musisz nadać uprawnienie EXECUTE.
źródło
Podałem wartości bez cudzysłowów. Kiedy spełniłem warunki wewnątrz, pojedyncze cudzysłowy działały jak urok.
Select * from emp_table where emp_id=123;
zamiast powyższego użyj tego:
Select * from emp_table where emp_id='123';
źródło