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_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
已将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:协议适配器错误怎么办?急!!!!!