当前位置: 首页 > 面试题库 >

使用JDBC以SYS_REFCURSOR作为IN参数调用PL / SQL过程

谷泳
2023-03-14
问题内容

我试图了解如何调用以SYS_REFCURSORas为IN参数的PL / SQL过程。

考虑以下PL / SQL过程:

print_cursor_contents(myCursor SYS_REFCURSOR , row_count OUT NUMBER);

在将值绑定到IN参数时,setXXX我应该使用哪种方法?

对我来说,一个具有单独的游标记录字段的Java类,因为它是该类的成员和实例数组,它似乎是表示plsql
CURSOR的正确方法。当我这样做时,我得到一个SQLException:

我使用了以下设置方法

         callStmt.setObject(1, curRec);

这是我使用上面的语句得到的例外:

Exception occured in the database
Exception message: Invalid column type
java.sql.SQLException: Invalid column type
    at oracle.jdbc.driver.OraclePreparedStatement.setObjectCritical(OraclePreparedStatement.java:8921)
    at oracle.jdbc.driver.OraclePreparedStatement.setObjectInternal(OraclePreparedStatement.java:8396)
    at oracle.jdbc.driver.OraclePreparedStatement.setObjectInternal(OraclePreparedStatement.java:9176)
    at oracle.jdbc.driver.OracleCallableStatement.setObject(OracleCallableStatement.java:5024)
    at oracle.jdbc.driver.OraclePreparedStatementWrapper.setObject(OraclePreparedStatementWrapper.java:234)
    at com.rolta.HrManager.printMaxSalAllDept(HrManager.java:1022)
    at com.rolta.HrManager.main(HrManager.java:1116)
Database error code: 17004

问题答案:

对我来说,一个具有单独的游标记录字段的Java类,因为它是该类的成员和实例数组,它似乎是表示plsql CURSOR的正确方法。

我不同意。

如果您有一个存储的函数或过程返回了ref游标或将ref游标作为OUT参数,则ref游标以形式出现在JDBC中ResultSet。因此,如果可以使用SYS_REFCURSOR参数调用存储过程,我怀疑a
ResultSet是您需要传递的内容。

实际上,我的怀疑得到了证实。如果你看一看Oracle的扩展CallableStatementOracleCallableStatement,它继承了setCursor(int, ResultSet)其超接口方法OraclePreparedStatement。因此,您可以将转换CallableStatementOracleCallableStatement,调用setCursor方法,然后离开。

除了这种方法实际上不起作用。

如果尝试调用setCursoran OracleCallableStatement,则会出现异常java.sql.SQLException: Unsupported feature

你可以尝试调用setObjectResultSet,但你只会得到另一个java.sql.SQLException: Invalid column type例外。

这是您可以运行以验证任一情况的测试类。它调用一个存储过程来获取ref游标(并因此获得ResultSet),然后尝试将其传递给另一个:

import java.sql.*;
import oracle.jdbc.OracleTypes;
import oracle.jdbc.OracleCallableStatement;

public class JavaRefCursorTest {
    public static void main(String[] args) throws Exception {
        Connection conn = DriverManager.getConnection(
                "jdbc:oracle:thin:@localhost:1521:XE", "user", "password");

        try (CallableStatement cstmt1 = conn.prepareCall(
                "{ call java_ref_curs_test.get_ref_cursor(?)}")) {
            cstmt1.registerOutParameter(1, OracleTypes.CURSOR);
            cstmt1.execute();

            try (ResultSet rSet = (ResultSet)cstmt1.getObject(1)) {
                try (CallableStatement cstmt2 = conn.prepareCall(
                        "{ call java_ref_curs_test.print_refcursor(?)}")) {

                    // Uncomment the next line to call setCursor:
                    // ((OracleCallableStatement)cstmt2).setCursor(1, rSet);

                    // Uncomment the next line to call setObject:
                    // cstmt2.setObject(1, rSet);

                    cstmt2.execute();
                }
            }
        }
    }
}

(采用java_ref_curs_test单个SYS_REFCURSOR参数的两个过程:get_ref_cursor返回一个ref游标,print_refcursor并将一个作为参数,但不执行任何操作。)

那么,setXXX您应该使用哪种方法?我什么也不会说。您要的内容无法直接实现。

仍然可以调用此过程,但是您必须在PL / SQL(而不是Java)中创建ref游标,然后将其传递给过程。

例如,我可以使用以下PL / SQL块来调用以上示例中使用的两个过程:

DECLARE
   l_curs   SYS_REFCURSOR;
BEGIN
   java_ref_curs_test.get_ref_cursor(l_curs);
   java_ref_curs_test.print_refcursor(l_curs); 
END;

您可以从JDBC轻松运行此代码:将其放入字符串中并将其传递给Statement.executeUpdate()



 类似资料:
  • 我试图从JDBC调用以下pl/sql过程。 这就是我试图调用它的方式,但没有成功: 我刚刚读到oracle jdbc不支持pl/sql结构类型。因此,这在“无效名称模式:test.testrec_r”中失败 如何从Java调用这个过程?理想情况下,只使用java库/API,但这似乎几乎是不可能的,在简单的sql调用中封装pl/sql包并调用它的最佳解决方案是什么? 另外,我正在使用Spring J

  • 我需要对一个参数为PL/SQL表的过程进行JDBC调用。我正在尝试结构对象。但是我没有做正确的事情。我得到错误: ORA-04043:对象“斯科特”。“对象列表结构”不存在。 以下是代码片段: 参数“?”对于本程序,类型为: 我们非常感谢任何能让我们成功的见解谢谢

  • 我想用java调用一个记录类型表的存储过程。记录只包含数字,但我必须传递整数和小数。 我还没有为我的问题找到合适的解决方案(无论是OracleCallableStatement还是StoredProcedurey)。

  • 问题内容: 我的包体内有一个proc: 我在包装规格中公开了这一点。 如何在PL SQL Developer(或类似版本)的新SQL窗口中执行此过程? 问题答案: 您可以相对轻松地执行该过程 当然,这只是将游标返回到调用应用程序。它不执行任何操作来从游标中获取数据,对该数据执行任何操作或关闭游标。假设您的目标是向其中写入一些数据(有时对于原型设计很有用,但生产代码不应该依赖该数据),则可以执行以下

  • 我试图创建一个以记录类型为参数的过程。我的问题是,我不能在过程之前定义我的类型,它说我的类型没有声明。。我该怎么做? 这是我的代码: 错误(1,29):PLS-00201:必须声明标识符“TIP”

  • 我有一个函数,它在PL/SQL中返回一个布尔值。我曾尝试直接获取那个布尔值,但没有成功,所以现在我试图将其转换为字符串(我不想修改数据库): 此代码在数据库中正常工作: