如何在 java 中映射 TYPE TABLE OF VARCHAR2(5)?

How to map TYPE TABLE OF VARCHAR2(5) in java?

我有一个签名如下的程序。

CREATE OR REPLACE PACKAGE BODY MYSCHEMA.MYPACK
AS
PROCEDURE GETBOX (DSSO_BoxNumber      IN     VARCHAR2,
CreateDateTime         OUT tCreateDateTime,
                          ReceiptDateTime        OUT tReceiptDateTime,
                          CSCBoxNumber           OUT tCSCBoxNumber,
                          DSSOBoxNumber          OUT tDSSOBoxNumber,
                          PackID                 OUT tPackID,
                          RequestID              OUT tRequestID,
                          ExceptionID            OUT tExceptionID,
                          Name                   OUT tName,
                          FolderID               OUT tFolderID,
                          ClosedDateTime         OUT tClosedDateTime,
                          OpenStatus             OUT tOpenStatus,
                          RequestOpenStatus      OUT tRequestOpenStatus,
                          RETURNED               OUT tRETURNED)
...

自定义类型定义如下。

CREATE OR REPLACE PACKAGE MYSCHEMA.MYPACK
  AS
      TYPE tCreateDateTime is TABLE of  VARCHAR2(15)
      INDEX BY BINARY_INTEGER;
      TYPE tReceiptDateTime is TABLE of VARCHAR2(15)
      INDEX BY BINARY_INTEGER;
      TYPE tCSCBoxNumber is TABLE of VARCHAR2(20)
      INDEX BY BINARY_INTEGER;
      TYPE tDSSOBoxNumber is TABLE of  VARCHAR2(20)
      INDEX BY BINARY_INTEGER;
      TYPE tPackID is TABLE of VARCHAR2(20)
      INDEX BY BINARY_INTEGER;
      TYPE tRequestID is TABLE of VARCHAR2(20)
      INDEX BY BINARY_INTEGER;
      TYPE tExceptionID is TABLE of  VARCHAR2(20)
...

谁能帮忙,如何在java中注册out参数?

我尝试了以下方法,但没有成功。

cs.setString(1, "XYZ123");
cs.registerOutParameter(2, Types.ARRAY,"MYSCHEMA.MYPACK.tCreateDateTime");
...

出现以下错误。

java.sql.SQLException: invalid name pattern: MYSCHEMA.MYPACK.tCreateDateTime
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:112)
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:146)
at oracle.jdbc.oracore.OracleTypeADT.initMetadata(OracleTypeADT.java:463)
at oracle.jdbc.oracore.OracleTypeADT.init(OracleTypeADT.java:362)
at oracle.sql.ArrayDescriptor.initPickler(ArrayDescriptor.java:1756)
at oracle.sql.ArrayDescriptor.<init>(ArrayDescriptor.java:272)
...

我们已经检查过该模式可以访问该过程,并且它是在主模式中定义的。我们还尝试为此包创建 public 同义词。还是不行..

您的问题标题具有误导性。 table of <TYPE>table of <TYPE> index by <TYPE> 是两种截然不同的数据类型。在 Oracle (PL/)SQL 中,第一个称为 嵌套 table,第二个称为 关联数组

主要问题是:

  • 显示给 Java 的 PL/SQL 接口中使用的 collection 类型需要是 SQL 类型,而不是 PL/SQL 类型
  • 关联数组不是 SQL 类型而是 PL/SQL 类型

第一个问题已解决,例如in How to return an array from Java to PL/SQL?(调用方向不同,问题相同)。

进一步阅读:

我能够将 varchar2 的类型 table 映射到 java,如下所示:

  1. 在任何 PLSQL 包之外创建一个新类型并授予必要的权限。

     CREATE OR REPLACE TYPE STRARRAY AS TABLE OF VARCHAR2 (100);
     /
     GRANT all ON MYSCHEMA.STRARRAY TO MYUSER1;
     /
     commit;
    
  2. 创建一个 accepts/returns strarray 的 PLSQL 函数。这是在包规范中声明的,并完整地写在包体中。虽然我将数组声明为 IN OUT,但在我的实现中我实际上只使用了 PLSQL 调用的输出。

    PROCEDURE getArr(arr_var IN OUT strarray) IS
      counter NUMBER := 1;
    BEGIN
      arr_var := new strarray();
      WHILE counter <= 10 LOOP
        arr_var.extend();
        arr_var(counter) := 'my data string';
      END LOOP;
    END getArr;
    
  3. 调用java中的过程。在此示例中,变量 conn 的数据类型为 Connection 并且已被初始化。我是 运行 一个针对 Oracle 数据库的 jdbc 瘦客户端。

    CallableStatement proc = null;
    String sql = "{ call myPackage.getArr(?) }";
    try{
      proc = conn.prepareCall(sql);
      proc.registerOutParameter(1, OracleTypes.Array, "MYSCHEMA.STRARRAY");
      proc.execute();
      Array arrOut = proc.getArray(1);
      for (int num=0; num<10; num++){
         System.out.println(arrOut[num]);
    }finally{
      proc.close();
    }