如何在 Java 中执行 Oracle PLSQL 块
Posted
技术标签:
【中文标题】如何在 Java 中执行 Oracle PLSQL 块【英文标题】:How to execute an Oracle PLSQL block in Java 【发布时间】:2015-09-16 17:25:35 【问题描述】:我有一个这样的 PL/SQL 块:
BEGIN
FOR i IN 1..100
LOOP
UPDATE rptbody
SET comments = 'abcs';
WHERE (rptno> 100 and rptno < 200) and ROWNUM<2;
COMMIT;
END LOOP;
END;
此块需要使用 Oracle JDBC 执行。我尝试了以下方法:
尝试使用 Statement 对象执行此操作。由于这是一个块,因此引发了一个异常,说这不是一个 sql 语句
这可以拆分为 sql 语句,但我有 100 多个这样的块,这对于代码来说会很麻烦,并考虑将其留给 sqlplus。
尝试使用 CallableStatement,但效果不佳。
任何解决方案都会有所帮助。
【问题讨论】:
你说得对,这是一个匿名的 PL/SQL 块而不是 SQL 您能否发布您正在使用的 Java 代码(尤其是CallableStatement
版本)?并发布你得到的确切错误堆栈。
结合 Justin 提到的内容,您可能会发现这有助于修复错误:***.com/a/10465239/350136
你可以通过Statement
对象运行它,但是你必须使用Statement.execute()
。如果 oyu 需要将参数传递给 PL/SQL 块,您只需要 CallableStatement
。您需要发布您的 Java 代码。 “不起作用”既不是可接受的错误描述,也不是有效的 Java 或 Oracle 异常
顺便说一句:我只是希望您的示例不是您正在运行的真实代码,因为在没有 PL/SQL 块的情况下使用单个语句可以更有效地实现很多 -而不是通过光标慢慢来的方法。
【参考方案1】:
这与您如何运行它无关。 PL/SQL 语法无效。在 WHERE
子句之前的更新子句之后有一个 ;
:
BEGIN
FOR i IN 1..100
LOOP
UPDATE rptbody
SET comments = 'abcs' --<<< no semicolon here!!
WHERE (rptno> 100 and rptno < 200) and ROWNUM<2;
COMMIT;
END LOOP;
END;
上面的代码可以这样运行:
String sql = "... the PL/SQL block ...";
Statement stmt = connection.createStatement();
stmt.execute(sql);
【讨论】:
【参考方案2】:查看一些代码示例以在 Github 上使用 CallableStatement 和 PreparedStatement
【讨论】:
【参考方案3】:尝试使用 Statement 对象执行此操作。由于这是一个块,因此引发了一个异常,说这不是一个 sql 语句
Since you were trying to execute a plsql block, you should not use Statement object.
来自https://docs.oracle.com/javase/7/docs/api/java/sql/Statement.html: 用于执行静态 SQL 语句并返回其产生的结果的对象。
这是你需要执行一个块的方式:
CallableStatement anonBlock = null // Note that CallableStatement is an interface
String anonBlockString = '' //Generally multi line
// Set in and out parameters as needed by your anonBlockString
anonBlock.registerOutParameter( <number> , <type> )
...
// executeUpdate() is inherited from PreparedStatement and can be used for executing DML statements (update, insert, delete)
anonBlock.executeUpdate();
To access out parameters:
anonBlock.getString(<number which you have assigned in registerOutParameter() calls);
完整示例:(https://download.oracle.com/otn_hosted_doc/timesten/1121/quickstart/sample_code/jdbc/plsqlJDBC.java)
这可以拆分成 sql 语句,但是我有 100 个这样的块,这对于代码来说会很麻烦,所以我想把它留给 sqlplus。
更喜欢使用存储过程而不是匿名块。由于存储过程以经过编译和优化的格式存储,因此与匿名存储过程相比,它们具有性能提升
尝试了 CallableStatement,但效果不佳:
代码是什么,错误/堆栈?
【讨论】:
以上是关于如何在 Java 中执行 Oracle PLSQL 块的主要内容,如果未能解决你的问题,请参考以下文章
从Oracle PLSQL调用java时如何将参数传递给java
从plsql调用java时Oracle如何导入缺少的java类