![](/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.