使用Java中的数组输出参数调用Oracle存储过程

使用Java中的数组输出参数调用Oracle存储过程,java,oracle,jdbc,plsql,callable-statement,Java,Oracle,Jdbc,Plsql,Callable Statement,我在从Java调用plsql过程时遇到问题。包含过程的包如下:(schemajob\u runner和连接用户/方案不同): 然后我尝试用callableStatement从Java调用它: final String typeTableList = "SOME_TABLE_TYPE"; CallableStatement cs = null; try (Connection con = dataSource.getConnection()) { con.

我在从Java调用plsql过程时遇到问题。包含过程的包如下:(schema
job\u runner
和连接用户/方案不同):

然后我尝试用callableStatement从Java调用它:

    final String typeTableList = "SOME_TABLE_TYPE";

    CallableStatement cs = null;
    try (Connection con = dataSource.getConnection()) {
        con.setSchema("JOB_RUNNER");

        cs = con.prepareCall("{call job_runner.test_package_for_sp.proc_table(?, ?, ?)}");

        cs.setString(1, "54867321");
        cs.setDate(2, Date.valueOf(ZonedDateTime.now().minusDays(200).toLocalDate()));
        cs.registerOutParameter(3, Types.ARRAY, typeTableList);

        cs.execute();
    } finally {
        if (cs != null)
            cs.close();
    }
错误提示:

java.sql.SQLException: invalid name pattern: <connection_scheme>.SOME_TABLE_TYPE

    at oracle.jdbc.oracore.OracleTypeADT.initMetadata11_2(OracleTypeADT.java:764)
    at oracle.jdbc.oracore.OracleTypeADT.initMetadata(OracleTypeADT.java:479)
    at oracle.jdbc.oracore.OracleTypeADT.init(OracleTypeADT.java:443)
有人知道如何从java调用这个过程吗

方法之一:

package testproject;

import java.sql.Array;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Types;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.CallableStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import oracle.sql.ARRAY;

import oracle.jdbc.OracleCallableStatement;

import oracle.sql.ArrayDescriptor;

    public class MainClass {
    public MainClass() {
        super();
    }

    public static void main(String[] args) {
        MainClass mainClass = new MainClass();

        Connection conn = null;

        ArrayDescriptor des = null;

        try {

            Object[] obj1 = { 1, "2017-01-01 10:12:10", 200 };
            Object[] obj2 = { 2, "2017-06-01 10:12:10", 600 };
            Object[] obj3 = { 3, "2017-08-01 10:12:10", 990 };

            conn =
DriverManager.getConnection("jdbc:oracle:thin:@<DB_HOST>",
                            "<user>", "<pass>");

          try {
              des = ArrayDescriptor.createDescriptor("AJ_TEST_OBJ_TBL", conn);
          } catch (SQLException e) {
              System.out.println("Arraydesc went wrong.");
              System.out.println(e.getStackTrace());
          }

          ARRAY nArray =
              new ARRAY(des, conn, new Object[] { obj1, obj2, obj3 });

            OracleCallableStatement pstmt =
                (OracleCallableStatement)conn.prepareCall("begin 
aj_test_array_pck.print_tbl_parameters(?,?); end;");

            pstmt.setArray(1, nArray);
            pstmt.registerOutParameter(2, Types.VARCHAR);
            pstmt.execute();

            String status = pstmt.getString(2);
            System.out.println("Status: " + status);

            pstmt.close();
            conn.close();
        } catch (SQLException e) {
            System.out.println("Oops with select");
            System.out.println(e.getStackTrace());
        } catch (ClassNotFoundException e) {
            System.out.println("Oops with class");
        }
    }

}
包测试项目;
导入java.sql.Array;
导入java.sql.CallableStatement;
导入java.sql.Connection;
导入java.sql.DriverManager;
导入java.sql.SQLException;
导入java.sql.Types;
导入java.sql.Connection;
导入java.sql.DriverManager;
导入java.sql.CallableStatement;
导入java.sql.ResultSet;
导入java.sql.SQLException;
导入oracle.sql.ARRAY;
导入oracle.jdbc.OracleCallableStatement;
导入oracle.sql.ArrayDescriptor;
公共类主类{
公共类(){
超级();
}
公共静态void main(字符串[]args){
MainClass MainClass=新的MainClass();
连接conn=null;
ArrayDescriptor des=null;
试一试{
对象[]obj1={1,“2017-01-01 10:12:10”,200};
对象[]obj2={2,“2017-06-01 10:12:10”,600};
对象[]obj3={3,“2017-08-01 10:12:10”,990};
康涅狄格州=
getConnection(“jdbc:oracle:thin:@”,
"", "");
试一试{
des=ArrayDescriptor.createDescriptor(“AJ_TEST_OBJ_TBL”,康涅狄格州);
}捕获(SQLE异常){
System.out.println(“Arraydesc出错”);
System.out.println(e.getStackTrace());
}
阵列天线=
新数组(des、conn、新对象[]{obj1、obj2、obj3});
OracleCallableStatement pstmt=
(OracleCallableStatement)conn.prepareCall(“开始
aj_测试_阵列_pck.打印_tbl_参数(?),结束;“”;
pstmt.setArray(1,nArray);
pstmt.registerOutParameter(2,Types.VARCHAR);
pstmt.execute();
字符串状态=pstmt.getString(2);
System.out.println(“状态:+状态”);
pstmt.close();
康涅狄格州关闭();
}捕获(SQLE异常){
System.out.println(“带select的Oops”);
System.out.println(e.getStackTrace());
}catch(classnotfounde异常){
System.out.println(“类的Oops”);
}
}
}

其中“AJ_TEST_OBJ_TBL”是一个SQL类型的对象。

您可以将JDBC连接属性
“oracle.JDBC.createDescriptorUseCurrentSchemaForSchemaName”
设置为
“true”
,然后将模式切换为
“job_runner”
更改会话设置当前模式=job_runner
)使用
TEST\u PACKAGE\u作为SP.SOME\u TABLE\u TYP
作为typeTableList.

1)创建SQL类型(“创建type SOME\u record\u type as object(..)”)2)使用oracle java arraydescriptor,在过程中识别并传递类型@在内部调用Ychdziu Arraydescriptor(位于oracle.sql.Arraydescriptor.createDescriptor(Arraydescriptor.java:79))。而这个类已被弃用。你能举一些例子来说明如何识别类型并将类型从arraydescriptor传递到过程吗?是的,我在那里看到过这个例子,但它的例子中有
IN
array param,而不是
OUT
,正如我之前所说的那样,
arraydescriptor.createDescriptor
,IN参数是已定义的数组,out只是一个简单的varchar,带有结果E/S,只是为了看看过程是否完成了它的工作。主要方面是,将您的类型定义为SQL类型,而不是PL/SQL类型。多亏了注释,但这同样不起作用。错误是:
java.sql.SQLException:无效的名称模式:在oracle.jdbc.oracore.OracleTypeADT.initMetadata11_2(OracleTypeADT.java:764)在oracle.jdbc.oracore.OracleTypeADT.initMetadata(OracleTypeADT.java:479)在oracle.jdbc.OracleTypeADT.OracleTypeADT.init(OracleTypeADT.java:443)上测试SP.SP.SOME.SOME.SOME.SOME表格类型的包在oracle.sql.ArrayDescriptor.initPickler(ArrayDescriptor.java:1499)
您使用的是哪个版本的驱动程序?11.2或12.1或12.2?也许是18c?执行java-jar ojdbcX.jar以查找驱动程序版本:12.2.0.1我怀疑数据库版本早于该版本(12.2),因为Oracle中标识符的最大长度在12.2中从30扩展到128。您的数据库版本是什么?是的,oracle 11.2.0.4.0。谢谢,这似乎与此有关。
java.sql.SQLSyntaxErrorException: ORA-01948: identifier's name length (35) exceeds maximum (30)
ORA-06512: at "SYS.DBMS_PICKLER", line 18
ORA-06512: at "SYS.DBMS_PICKLER", line 58
ORA-06512: at line 1


    at oracle.jdbc.driver.T4CTTIoer11.processError(T4CTTIoer11.java:494)
package testproject;

import java.sql.Array;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Types;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.CallableStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import oracle.sql.ARRAY;

import oracle.jdbc.OracleCallableStatement;

import oracle.sql.ArrayDescriptor;

    public class MainClass {
    public MainClass() {
        super();
    }

    public static void main(String[] args) {
        MainClass mainClass = new MainClass();

        Connection conn = null;

        ArrayDescriptor des = null;

        try {

            Object[] obj1 = { 1, "2017-01-01 10:12:10", 200 };
            Object[] obj2 = { 2, "2017-06-01 10:12:10", 600 };
            Object[] obj3 = { 3, "2017-08-01 10:12:10", 990 };

            conn =
DriverManager.getConnection("jdbc:oracle:thin:@<DB_HOST>",
                            "<user>", "<pass>");

          try {
              des = ArrayDescriptor.createDescriptor("AJ_TEST_OBJ_TBL", conn);
          } catch (SQLException e) {
              System.out.println("Arraydesc went wrong.");
              System.out.println(e.getStackTrace());
          }

          ARRAY nArray =
              new ARRAY(des, conn, new Object[] { obj1, obj2, obj3 });

            OracleCallableStatement pstmt =
                (OracleCallableStatement)conn.prepareCall("begin 
aj_test_array_pck.print_tbl_parameters(?,?); end;");

            pstmt.setArray(1, nArray);
            pstmt.registerOutParameter(2, Types.VARCHAR);
            pstmt.execute();

            String status = pstmt.getString(2);
            System.out.println("Status: " + status);

            pstmt.close();
            conn.close();
        } catch (SQLException e) {
            System.out.println("Oops with select");
            System.out.println(e.getStackTrace());
        } catch (ClassNotFoundException e) {
            System.out.println("Oops with class");
        }
    }

}