【问题标题】:How to execute an Oracle PLSQL block in Java如何在 Java 中执行 Oracle PLSQL 块
【发布时间】: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 提到的内容,您可能会发现这有助于修复错误:stackoverflow.com/a/10465239/350136
  • 可以通过Statement对象运行它,但是你必须使用Statement.execute()。如果 oyu 需要将参数传递给 PL/SQL 块,您只需要 CallableStatement。您需要发布您的 Java 代码。 “不起作用”既不是可接受的错误描述,也不是有效的 Java 或 Oracle 异常
  • 顺便说一句:我只是希望您的示例不是您正在运行的真实代码,因为在没有 PL/SQL 块的情况下使用单个语句可以更有效地实现很多 -而不是通过光标慢慢来的方法。

标签: java sql oracle jdbc plsql


【解决方案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,但效果不佳:

      代码是什么,错误/堆栈?

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-01-16
        • 1970-01-01
        • 2015-11-01
        • 2015-03-02
        • 1970-01-01
        相关资源
        最近更新 更多