Как отобразить TYPE TABLE OF VARCHAR2 (5) в Java?

1

У меня есть процедура с подписью ниже.

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)
...

Определения типа cutom приведены ниже.

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?

Я пробовал следующее, но не повезло.

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)
...

Мы проверили, что схема имеет доступ к процедуре и определена в мастер-схеме. Мы также попытались создать публичный синоним этого пакета. Все еще не работает..

  • 0
    Выглядит как очень плохой дизайн, когда такие параметры, как tReceiptDateTime имеют тип VARCHAR2(15) вместо DATE или TIMESTAMP . В любом случае, очевидно, что вы назначаете целую таблицу для вашей процедуры, возможно, было бы проще назначить RefCursor вместо этого.
  • 0
    @Wernfrid: спасибо за ваше предложение. Я также попробовал тип курсора cs.registerOutParameter(2, OracleTypes.CURSOR,"DMD2.packcontents.tCreateDateTime"); , Как назначить RefCursor ?
Показать ещё 1 комментарий
Теги:
spring
plsql

2 ответа

2
Лучший ответ

Название вашего вопроса вводит в заблуждение. table of <TYPE> и table of <TYPE> index by <TYPE> - это два очень разных типа данных. Сначала называется вложенной таблицей, а вторая называется ассоциативным массивом в языке SQL (PL/) SQL.

Основные проблемы заключаются в следующем:

  • типы коллекций, используемые в интерфейсах PL/SQL, выявленные для Java, должны быть типами SQL, а не типами PL/SQL
  • ассоциативный массив не является типом SQL, но тип PL/SQL

Первая проблема рассматривается, например, в разделе Как вернуть массив из Java в PL/SQL? (проблема такая же, даже направление вызова отличается).

Дальнейшее чтение:

  • 0
    Спасибо за ответ. Проблема решается после разделения типов вне пакета, т. Е. После создания набора типов SQL.
1

Мне удалось сопоставить таблицу типов varchar2 с java следующим образом:

  1. Создайте новый тип вне любого пакета PLSQL и предоставите необходимые разрешения.

     CREATE OR REPLACE TYPE STRARRAY AS TABLE OF VARCHAR2 (100);
     /
     GRANT all ON MYSCHEMA.STRARRAY TO MYUSER1;
     /
     commit;
    
  2. Создайте функцию PLSQL, которая принимает/возвращает strarray. Это было объявлено в спецификации пакета и полностью написано в корпусе пакета. Хотя я объявлял массив IN IN, в моей реализации я использую только результат вызова 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 и уже инициализирована. Я использую тонкий клиент jdbc для базы данных Oracle.

    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();
    }
    

Ещё вопросы

Сообщество Overcoder
Наверх
Меню