PL/SQL JAVA ORACLE 错误 ORA-00904: 标识符无效

Posted

技术标签:

【中文标题】PL/SQL JAVA ORACLE 错误 ORA-00904: 标识符无效【英文标题】:PL/SQL JAVA ORACLE ERROR ORA-00904: INVALID IDENTIFIER 【发布时间】:2017-04-30 19:21:20 【问题描述】:

当我运行我的程序时出现错误:

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;

【问题讨论】:

你尝试调用函数了吗? 是的,功能有效。 也许这就是你需要的***.com/questions/26550465/… 【参考方案1】:

SELECT 的语法错误:

String sql = "SELECT pacjent_oddzial ("+Login.login+") from dual";

该查询的结果应如下所示:

SELECT pacjent_oddzial (some_string) from dual
-- ------------------------^^^^^^

这不是正确的语法。


如果您尝试调用您的函数,那么这也不正确,您可以使用以下语法:

? = call CREATE_A_PERSON (?)
 1              2          3

哪个:

(1) 是返回值 (2) 函数的名称 (3) 是你方法的参数 字符串查询 = "? = 调用 pacjent_oddzial (?)"; CallableStatement stm = conn.prepareCall(query); stm.registerOutParameter(1, Types.VARCHAR);//返回值 stm.setString(2, Login.login);//设置参数 String return = stm.getString(1);//你的函数的结果

在这里看看:

JDBC CallableStatement – Stored Procedure OUT parameter example

【讨论】:

【参考方案2】:

一般来说,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_raiseGIVE_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 已将SELECT 上的EMPLOYEES 授予Joe。 Joe 仍然不能只使用select * from employees,因为他必须说出它在哪里,而不是像需要指定文件系统中的路径或其他语言中的点表示法一样。默认是当前模式,即JOE.EMPLOYEES,当然不存在。那么选项是:

    明确参考HR.EMPLOYEES(尽管硬编码并不理想)。 为 HR.EMPLOYEES 创建一个公共同义词(但由于公共同义词的全局性质,可能会限制您以后的选择,而且它会广播您的对象名称,这可能是一个安全问题)。 在JOE 架构中为HR.EMPLOYEES 创建一个私有同义词。 让 Joe 使用 alter session set current_schema = HR 将他的默认架构设置为 HR

【讨论】:

【参考方案3】:

你的 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);

【讨论】:

以上是关于PL/SQL JAVA ORACLE 错误 ORA-00904: 标识符无效的主要内容,如果未能解决你的问题,请参考以下文章

ORACLE:错误错误(6,3):PL/SQL:SQL 语句被忽略和错误(8,3):PL/SQL:ORA-00933:SQL 命令未在过程中正确结束

PL/SQL ORA-01422 SELECT INTO 错误,Oracle 匿名块(NOVA 环境)

oracle ORA-06502:PL/SQL:数字或值错误:批量绑定:截断绑定

oracle 11g ORA-06502:PL/SQL:数字或值错误:字符串缓冲区太小

我用PL/SQL-Developer登录oracle时出现 ORA-12560:TNS:协议适配器错误怎么办?急!!!!!

在 Oracle 11g2 XE 中编译 PL/SQL 函数有时会导致 ORA-00600:内部错误