将参数传递给 callableSatatement - ORA-01008:并非所有变量都绑定

问题描述

我有一个带参数的 PL/sql 查询

plsqlQuery =    "declare "
              + "  num integer := 1000;"
              + "  myStr varchar2(100):= ?;"
              + "begin "
              + "  dbms_output.put_line('abc');"
              + "  dbms_output.put_line('hello');"
              + "  dbms_output.put_line(myStr);"
              + "end;"

我的 Java 方法是这样的:

public static void getData(String sqlQuery) throws sqlException,IOException{
    Statement s =conn.createStatement();
    try{
    s.executeUpdate("begin dbms_output.enable();end;);
    s.executeUpdate(sqlQuery);
    
    try{
    CallableStatement call = conn.prepareCall("declare num integer = 10000; begin dbms_output.get_lines(?,num); end;)
    }
    call.registerOutParameter(1,Types.ARRAY,"DBMSOUTPUT_LInesARRAY");
    call.execute();
    
     Array array = null;
                    try {
                        array = call.getArray(1);
                        System.out.println(Arrays.asList((Object[]) 
                 array.getArray()));
                    }
                    finally {
                        if (array != null)
                            array.free();
                    }

现在有了以上两个,我想执行我的 getData 方法,但我不知道如何向它传递参数 (myStr)。

你能告诉我应该在我的 Java 方法中的哪个位置设置我的字符串参数吗?

应该是这样的

s.setString(x,"abcdefg");

call.setString(2,"abcdefg");

它给了我一个 Oracle 错误,比如

ORA-01008:并非所有变量都绑定

老实说,我尝试了这两种方法,但没有成功。

解决方法

如果您将字符串 plSqlQuery 作为参数传递给您的 getData() 方法(例如通过调用 getData(plSqlQuery)),那么您将遇到 ORA-01008 'not all variables bound'错误,因为您没有为 ? 占位符指定值。

不能将普通的 Statement 与占位符一起使用,而必须使用 PreparedStatement

尝试替换该行

    s.executeUpdate(sqlQuery);

    try (PreparedStatement pstmt = conn.prepareStatement(sqlQuery)) {
        pstmt.setString(1,"Some Value Here");
        pstmt.execute();
    }
,

我想通了。 它适用于 3 个不同的语句:(

Statement s = conn.createStatement();
s.executeUpdate("begin dbms_output.enable();end;);

PreparedStatement ps = conn.prepareStatement(sqlQuery);
ps.setString(1,"abcdefg");

 CallableStatement call = conn.prepareCall("declare num integer = 10000; begin dbms_output.get_lines(?,num); end;)
 call.registerOutParameter(1,Types.ARRAY,"DBMSOUTPUT_LINESARRAY");
 call.execute();