1

从 Java 调用存储过程时出现以下错误:

“java.sql.SQLException:[Oracle][ODBC][Ora]ORA-06550:第 1 行,第 7 列:PLS-00306:调用 'GET_NEW_EVENTS' ORA-06550:第 1 行,第 1 列的参数数量或类型错误7: PL/SQL: 语句被忽略”

存储过程如下:

    create or replace package body event_subscription as
    procedure get_new_events( p_events in out SYS_REFCURSOR ) as
    begin
        open p_events for
            select log_id from event_alert_log;         
    end get_new_events;
end event_subscription;

调用存储过程的Java代码如下:

    sqlString = "BEGIN event_subscription.get_new_events(?); END;";
CallableStatement  cs = connection.prepareCall(sqlString);
cs.registerOutParameter(1,OracleTypes.CURSOR);
cs.execute(); // This line is failing and throwing the SQLException
ResultSet rs = (ResultSet) cs.getObject(1);

Oracle 版本为:Oracle Database 10g Express Edition Release 10.2.0.1.0 - 产品 Java 版本为:1.6。

有人可以在这个问题上帮助我。我一直在尝试所有可能的解决方案来解决这个问题。

4

2 回答 2

1

奇怪的。我无法重现这个。我在 Windows 7 x64 上使用 Oracle XE 11.2.0.2.0,版本 11.2.0.2.0 为ojdbc6.jar.

我没有你的表,所以我查询了一个数据字典视图。我创建了以下包

create or replace package event_subscription as
   procedure get_new_events( p_events out SYS_REFCURSOR );
end;

create or replace package body event_subscription as
    procedure get_new_events( p_events out SYS_REFCURSOR )
    as
    begin
        open p_events for
            select object_name, object_type from all_objects where rownum <= 10;
    end get_new_events;
end event_subscription;

并编译了以下 Java 类:

import java.sql.*;

public class So12751878 {
    public static void main(String[] args) throws Exception {
        new oracle.jdbc.OracleDriver();
        Connection connection = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:XE", "user", "password");
        String sqlString = "BEGIN event_subscription.get_new_events(?); END;";
        CallableStatement cs = connection.prepareCall(sqlString);
        cs.registerOutParameter(1, oracle.jdbc.OracleTypes.CURSOR);
        cs.execute();
        ResultSet rs = (ResultSet) cs.getObject(1);
        while (rs.next()) {
            System.out.println("Got '" + rs.getString(1) + "' and '" + rs.getString(2) + "'.");
        }
    }
}

这运行成功。OUT如果我将存储过程的参数从更改为 ,它也可以成功运行IN OUT

编辑:您现在已经在评论中澄清您正在使用 JDBC-ODBC 桥驱动程序连接到 Oracle。但是,您将参数的类型注册为oracle.jdbc.OracleTypes.CURSOR. 这种类型特定于 Oracle JDBC 驱动程序,因此我不希望 JDBC-ODBC 桥驱动程序能够理解,因为它必须支持多个数据库。

OracleTypes.*故事的寓意:如果使用常量,请不要使用 JDBC-ODBC 桥驱动程序连接到 Oracle 。更好的是,不要使用 JDBC-ODBC 桥驱动程序连接到 Oracle。

于 2012-10-05T22:36:15.917 回答
0

那是因为你有一个IN OUT参数,所以你必须设置IN,例如:

cs.setInt(1, -2);

然后是你已经拥有的超参数。两个都。

cs.registerOutParameter(1,OracleTypes.CURSOR); 

您遇到的问题是光标 IN... 不能作为 IN 参数工作。你真的要发送一个 refcursor 作为参数吗?

于 2012-10-05T19:48:55.350 回答