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

PL/SQL JAVA ORACLE错误ORA-00904:标识符无效,java,oracle,jdbc,plsql,Java,Oracle,Jdbc,Plsql,当我运行程序时,出现了一个错误: ORACLE ERROR ORA-00904: "PACJENT_ODDZIAL": INVALID IDENTIFIER 我不知道哪里有问题。 我正在使用NetBeans和sqldeveloper 以下是我的Java代码: private String PacjentOddzial() { String PacjentOddzial = "null"; con = Polaczenie.ConnectDB(); String sq

当我运行程序时,出现了一个错误:

ORACLE ERROR ORA-00904: "PACJENT_ODDZIAL": INVALID IDENTIFIER
我不知道哪里有问题。
我正在使用NetBeans和sqldeveloper

以下是我的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
其中:

  • (1) 是返回值
  • (2) 函数的名称
  • (3) 是方法的参数
字符串查询=“{?=调用pacjent_oddzial(?)}”; CallableStatement stm=conn.prepareCall(查询); stm.registerOutParameter(1,Types.VARCHAR)//返回值 stm.setString(2,Login.Login)//设置参数 String return=stm.getString(1)//函数的结果 看看这里:


通常,ORA-00904错误意味着数据库无法看到您所指的内容。因此,要么:

  • 它真的不存在,至少不是你打字的方式。检查拼写,在数据字典(
    all_objects
    etc)中查找它,或者在声明它的地方检查它是否是代码项,检查你是否在引用过程时将其视为函数,反之亦然,检查是否涉及任何双引号标识符,因为它们区分大小写
  • 它确实存在,但您的帐户无法看到它。检查授权和同义词,并确保您作为正确的用户连接
  • 关于过程与函数,假设您创建了一个名为
    give_raise
    的过程。现在你可以这样称呼它:

    begin
        give_raise(123, 10);
    end;
    
    select give_raise(empno, 10) from employees;
    
    或者这个:

    call give_raise(123, 10);
    
    但不是这样:

    begin
        give_raise(123, 10);
    end;
    
    select give_raise(empno, 10) from employees;
    
    因为程序和功能是两个不同的东西

    关于双引号标识符,默认情况下名称不区分大小写,因此您可以互换地引用
    give_-raise
    give_-raise
    等,因为SQL解析器和PL/SQL编译器在内部将所有内容都大写作为第一步。但是,双引号使其区分大小写(同时允许使用其他通常无效的名称,如
    “012疯狂哈?”
    )。如果你把你的过程命名为“GiveRaise”(用引号括起来),那么这就是你必须永远引用它的方式

    此外,在Oracle SQL中,可以对别名项执行一些操作,也不能执行这些操作。例如,您可以在
    order by
    子句中引用别名:

    select dummy as myalias from dual
    order by myalias;
    
    /* Invalid, gives ORA-00904: */
    select dummy as myalias from dual
    group by myalias;
    
    但不在
    group by
    子句中:

    select dummy as myalias from dual
    order by myalias;
    
    /* Invalid, gives ORA-00904: */
    select dummy as myalias from dual
    group by myalias;
    
    关于权限,请注意,PL/SQL(
    create procedure
    etc)中存储的标准定义者权限不使用角色,因此即使您以拥有
    HR\u QUERY
    角色的
    JOE
    身份登录,并且JOE的SQL查询可以访问HR中的所有内容,Joe的存储过程只能看到他自己的对象和直接授予他的任何内容(不是通过角色)

    关于名称空间问题,假设用户
    HR
    已将
    SELECT
    on
    EMPLOYEES
    授予Joe。Joe仍然不能从employees中选择*,因为他必须说出它在哪里,就像需要在文件系统中指定路径,或者在其他语言中指定点符号一样。默认值是当前模式,即JOE.EMPLOYEES,当然不存在。那么选项是:

  • 请明确参考人力资源部员工(尽管硬编码并不理想)
  • HR.EMPLOYEES
    创建一个公共同义词(但由于公共同义词的全局性质,它可能会限制您以后的选择,而且它会广播您的对象名称,这可能是一个安全问题)
  • JOE
    模式中为
    HR.EMPLOYEES
    创建私有同义词
  • 让Joe使用
    alter session set current\u schema=HR
    将其默认模式设置为
    HR
  • 您的SQL来自此

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

    SELECT pacjent_oddzial (someLoginValue) from dual;
    
    SELECT pacjent_oddzial ('someLoginValue') from dual;
    
    。。。在本例中,参数是标识符,而不是字符串

    如果您通过引入单引号来更改sql

    String sql = "SELECT pacjent_oddzial ('" + Login.login + "') from dual";
    
    。。。变成

    SELECT pacjent_oddzial (someLoginValue) from dual;
    
    SELECT pacjent_oddzial ('someLoginValue') from dual;
    
    。。。应该可以工作,即使使用现有代码

    但是,您应该读入sql注入和绑定变量。将用户提供的值连接到sql中时,容易受到sql注入攻击。因此,您可能应该使用sql,比如

    String sql = "SELECT pacjent_oddzial (?) from dual";
    
    。。。然后通过…应用该值

    pst.setString(1, Login.login);
    

    你试过调用函数吗?是的,函数可以工作。也许这就是你需要的