У меня есть процедура с подписью ниже.
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)
...
Мы проверили, что схема имеет доступ к процедуре и определена в мастер-схеме. Мы также попытались создать публичный синоним этого пакета. Все еще не работает..
Название вашего вопроса вводит в заблуждение. table of <TYPE>
и table of <TYPE> index by <TYPE>
- это два очень разных типа данных. Сначала называется вложенной таблицей, а вторая называется ассоциативным массивом в языке SQL (PL/) SQL.
Основные проблемы заключаются в следующем:
Первая проблема рассматривается, например, в разделе Как вернуть массив из Java в PL/SQL? (проблема такая же, даже направление вызова отличается).
Дальнейшее чтение:
create type
базы данных SQL Language Reference.create type
оператор create type
Мне удалось сопоставить таблицу типов varchar2 с java следующим образом:
Создайте новый тип вне любого пакета PLSQL и предоставите необходимые разрешения.
CREATE OR REPLACE TYPE STRARRAY AS TABLE OF VARCHAR2 (100);
/
GRANT all ON MYSCHEMA.STRARRAY TO MYUSER1;
/
commit;
Создайте функцию 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;
Вызовите процедуру в 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();
}
tReceiptDateTime
имеют типVARCHAR2(15)
вместоDATE
илиTIMESTAMP
. В любом случае, очевидно, что вы назначаете целую таблицу для вашей процедуры, возможно, было бы проще назначитьRefCursor
вместо этого.cs.registerOutParameter(2, OracleTypes.CURSOR,"DMD2.packcontents.tCreateDateTime");
, Как назначитьRefCursor
?