![](/img/trans.png)
[英]java.sql.SQLSyntaxErrorException: ORA-00904: “columnName”: invalid identifier
[英]PL/SQL JAVA ORACLE ERROR ORA-00904: INVALID IDENTIFIER
當我運行我的程序時,我收到一個錯誤:
ORACLE ERROR ORA-00904: "PACJENT_ODDZIAL": INVALID IDENTIFIER
我不知道問題出在哪里。
我正在使用NetBeans和SQL Developer。
這是我的Java代碼:
private String PacjentOddzial() {
String PacjentOddzial = "null";
con = Polaczenie.ConnectDB();
String sql = "SELECT pacjent_oddzial (" + Login.login + ") from dual";
try {
pst = con.prepareStatement(sql);
rs = pst.executeQuery();
if (rs.next()) {
String add1 = rs.getString(1);
PacjentOddzial = add1;
}
} catch (SQLException | HeadlessException e) {
JOptionPane.showMessageDialog(null, e);
}
return PacjentOddzial;
}
這是PL / SQL函數:
create or replace FUNCTION pacjent_oddzial
(PES IN NUMBER)
RETURN VARCHAR2
IS
ILE VARCHAR2(30);
ZMIENNA NUMBER;
BEGIN
SELECT PACJENTID INTO ZMIENNA FROM PACJENT WHERE PESEL=PES;
SELECT NAZWAODDZIALU INTO ILE FROM PRZYJECIE_NA_ODDZIAL WHERE
PACJENTID=ZMIENNA and rownum=1;
RETURN ILE;
end;
SELECT的語法錯誤:
String sql = "SELECT pacjent_oddzial ("+Login.login+") from dual";
該查詢的結果應如下所示:
SELECT pacjent_oddzial (some_string) from dual
-- ------------------------^^^^^^
這不是一個正確的語法。
如果您嘗試調用函數,那么這也不正確您可以使用以下語法:
{? = call CREATE_A_PERSON (?)}
1 2 3
哪一個 :
String query = "{? = call pacjent_oddzial (?)}"; CallableStatement stm = conn.prepareCall(query); stm.registerOutParameter(1, Types.VARCHAR);//return value stm.setString(2, Login.login);//set the parametter String return = stm.getString(1);//the result of your function
看看這里:
通常,ORA-00904錯誤意味着數據庫無法看到您所指的東西。 所以要么:
all_objects
等)中查找它,或者如果它是一個代碼項,它在哪里聲明,檢查你是不是指一個過程就好像它是一個函數,反之亦然,檢查是否有任何雙引號標識符因為這些是區分大小寫的。 關於過程與函數,假設您創建了一個名為give_raise
的過程。 現在你可以像這樣調用它:
begin
give_raise(123, 10);
end;
或這個:
call give_raise(123, 10);
但不是這樣的:
select give_raise(empno, 10) from employees;
因為程序和功能是兩回事。
關於雙引號標識符,默認名稱不區分大小寫,因此您可以互換地引用give_raise
, GIVE_RAISE
等,因為SQL解析器和PL / SQL編譯器在內部將所有內容都作為第一步。 但是,雙引號會使其區分大小寫(以及允許其他通常無效的名稱,例如"012 Crazy huh?"
)。 如果您將程序命名為"GiveRaise"
(在引號中),那么您必須永遠引用它,引號和所有內容。
此外,在Oracle SQL中,您可以做和不能對別名項執行某些操作。 例如,您可以在order by
子句中引用別名:
select dummy as myalias from dual
order by myalias;
但不是在group by
子句中:
/* Invalid, gives ORA-00904: */
select dummy as myalias from dual
group by myalias;
關於權限,請注意標准的定義權限存儲的PL / SQL( create procedure
等)不使用角色,因此即使您已經以具有HR_QUERY
角色的JOE
登錄,並且Joe的SQL查詢可以訪問HR中的所有內容,但Joe存儲了程序只能看到自己的對象和直接授予他的任何東西(不是通過角色)。
關於命名空間問題,假設用戶HR
已將EMPLOYEES
上的SELECT
授予Joe。 Joe仍然不能只select * from employees
那里select * from employees
因為他必須說出它在哪里,而不是需要在文件系統中指定路徑,或者在其他語言中使用點符號。 默認值是當前架構,即JOE.EMPLOYEES
,當然不存在。 那么選項是:
HR.EMPLOYEES
(盡管硬編碼並不理想)。 HR.EMPLOYEES
創建一個公共同義詞(雖然由於公共同義詞的全局特性,以后可能會限制您的選項,並且它會廣播您的對象名稱,這可能是一個安全問題)。 JOE
模式中為HR.EMPLOYEES
創建一個私有同義詞。 HR
使用alter session set current_schema = HR
。 你的SQL來自......
String sql = "SELECT pacjent_oddzial (" + Login.login + ") from dual";
......變得......
SELECT pacjent_oddzial (someLoginValue) from dual;
...在這種情況下,參數是標識符,而不是字符串。
如果通過引入單引號來更改sql ...
String sql = "SELECT pacjent_oddzial ('" + Login.login + "') from dual";
......變得......
SELECT pacjent_oddzial ('someLoginValue') from dual;
......即使使用現有代碼也應該有效。
但是,您應該閱讀sql注入和綁定變量。 當您將用戶提供的值連接到sql時,您很容易受到SQL注入攻擊。 所以,相反,你應該使用像...這樣的SQL
String sql = "SELECT pacjent_oddzial (?) from dual";
...然后通過......應用價值
pst.setString(1, Login.login);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.