powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / Передача ARRAY в хранимую процедуру Oracle
25 сообщений из 25, страница 1 из 1
Передача ARRAY в хранимую процедуру Oracle
    #32415113
spainard
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Неправильно определяется тип данных Oracle при создании ArrayDescriptor
Код:
try {
DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
con = DriverManager.getConnection("jdbc:oracle:oci8:@mydb", "user", "pass");

for(int i=0;i<10;i++) scodes =new String("hello moto");

1. OracleCallableStatement cstmt = (OracleCallableStatement)con.prepareCall("{? = call Cheme.MyStorPr(?,?,?)}");
cstmt.registerIndexTableOutParameter(1,1000, OracleTypes.VARCHAR, 256);

2. ArrayDescriptor prices_AD = new ArrayDescriptor("ORANUMBER
", con);
3. ArrayDescriptor quant_AD = new ArrayDescriptor(" ORAINTEGER ", con);
4. ArrayDescriptor codes_AD = new ArrayDescriptor(" ORASTRING ", con);

5. System.out.println("--"+prices_AD.descType());
6. System.out.println("--"+quant_AD.descType());
7. System.out.println("--"+codes_AD.descType());

8. oracle.sql.ARRAY prices_ar = new oracle.sql.ARRAY(prices_AD, con, prices);
9. oracle.sql.ARRAY quant_ar = new oracle.sql.ARRAY(quant_AD, con, quant);
System.out.println("111");
10. oracle.sql.ARRAY codes_ar = new oracle.sql.ARRAY(codes_AD, con, scodes);
System.out.println("222");
11. cstmt.setARRAY(3, codes_ar);
12. cstmt.setARRAY(4, quant_ar);
13. cstmt.setARRAY(5, prices_ar);
14. cstmt.execute();
Datum[] str = cstmt.getOraclePlsqlIndexTable(1);
System.out.println(str.length);

}
catch(Exception ex)
{ System.err.println(ex); }

На 10 строке выдает ошибку, связанную с преобразованием типов в Integer. Строки 5 6 7 выдают следующее:
--ORANUMBER
NUMBER

--ORAINTEGER
NUMBER

--ORASTRING
NUMBER
Хотя в Oracle типы определются так:
create or replace type ORAInteger as table of integer
create or replace type ORANumber as table of number
create or replace type ORAString as table of varchar2(255)

Почему Number?
...
Рейтинг: 0 / 0
Передача ARRAY в хранимую процедуру Oracle
    #32415869
spainard
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Немного наладили
Теперь правильно определяется VARCHAR, не Number. В Oracle с create or replace были неясности.
Но массив к сожалению все равно не передается.
Ошибка:
oracle-character-set-171 17056
Подскажите, как быть с кодировкой? Текст в массиве строк на латинском, куда копать?. Хелп, плиз.
...
Рейтинг: 0 / 0
Передача ARRAY в хранимую процедуру Oracle
    #32416702
Фотография Denis Popov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А нельзя ли передавать все параметры единой объектной таблицей? По крайней мере у меня с кодировкой символов все в порядке, база - UTF8, на клиенте - CL8MSWIN1251.
How to pass an array from Java which maps to a PL/SQL table in oracle?

Дополнительно: раз уж используется OCI-драйвер, можно определить массив в Oracle как pl/sql-таблицу:

Oracle9i JDBC Developer's Guide and Reference Release 2 (9.2)
JDBC OCI Extensions
Accessing PL/SQL Index-by Tables

http://download-west.oracle.com/docs/cd/B10501_01/java.920/a96654/oci_func.htm#1017512

Там пример внизу дан.
...
Рейтинг: 0 / 0
Передача ARRAY в хранимую процедуру Oracle
    #32416726
Фотография Denis Popov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
Передача ARRAY в хранимую процедуру Oracle
    #32417064
spainard
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Спасибо за ответ, Денис.
Все параметры единой таблицей передавать не очень удобно, у них типы разные. Раньше строками передавали, проблемы с преобразованием строк в Number были. Вот, поэтому разделили.
Моя реализация передачи ARRAY похожа на ту,что в примерах, различий я не нашел.
С PL/SQL я еще обязательно посмотрю, но в чем разница между массивами или таблицей?

А вот с кодировкой..
Для коннекта я устанавливаю так:
DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
Properties info = new Properties();
info.put("user", dbuser);
info.put("password", dbpass);
info.put("charSet", "UTF8");
con = DriverManager.getConnection("jdbc:oracle:oci8:@mydb", info);
Но ошибка все равно не изчезает..
На сервере установлена CL8MSWIN1251. Сервер на WIN2000.
Странно, при чем здесь тогда вообще oracle-character-set-171? Ошибка 17056 - это Unsupported charset. Что ж делать..
...
Рейтинг: 0 / 0
Передача ARRAY в хранимую процедуру Oracle
    #32417147
Фотография Denis Popov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Все параметры единой таблицей передавать не очень удобно, у них типы разные.

Мне не совсем понятно, в чем может заключаться неудобство? Если создать объектный тип (или тип ARRAY в пакете) с набором полей, совпадающий с набором требуемых параметров, после чего создать объектную таблицу (или pl/sql-таблицу) на основе описанного типа и использовать его в процедурах?

Насчет info.put("charSet", "UTF8"); я не уверен - туда действительно можно именно "UTF8" передавать, это где-то указано? К слову, Properties для DriverManager'а я совсем не передаю, и у меня все работает:)
...
Рейтинг: 0 / 0
Передача ARRAY в хранимую процедуру Oracle
    #32417165
spainard
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Счас побробовал передавать строки как PL/SQL table - то же самое, ошибка oracle-character-set-171 17056 на строке cstmt.setPlsqlIndexTable..:
....
String[] st=new String[2];
st[0]="32432";
st[1]="32433";
cstmt.setPlsqlIndexTable(3, st, st.length, st.length, OracleTypes.VARCHAR, 255);
....
Конечно, можно объединить все в одну таблицу, только тогда не очень понятно как ее задать так, чтобы типы данных для каждого поля различались.. но это ладно пока, разобраться наверно можно..
Но.. я боюсь, что если таблица (или массив) с один полем (одномерный как бы) не передается, то при объединении ничего не измениться.
От Properties вообщем-то тоже ничего не меняется, можно передавать только пароль и логин, или Properties, результат тот же. Ох.
...
Рейтинг: 0 / 0
Передача ARRAY в хранимую процедуру Oracle
    #32417186
Фотография Denis Popov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Допустим, у тебя есть объектный тип, наподобе как в примере с CallInOutStructArray:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
create or replace type rectype as object (
    col1 number( 9 )
  , col2 varchar2( 10 )
  , col3 date
)
/
create or replace type rectab as table of rectype
/


Его ты и используешь.
...
Рейтинг: 0 / 0
Передача ARRAY в хранимую процедуру Oracle
    #32417248
spainard
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
В Oracle ясно, а как это в Java будет выглядеть не очень понятно, как этот массив или таблицу описать?
...
Рейтинг: 0 / 0
Передача ARRAY в хранимую процедуру Oracle
    #32417249
spainard
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Если можно пример в Java..
...
Рейтинг: 0 / 0
Передача ARRAY в хранимую процедуру Oracle
    #32417290
Фотография Denis Popov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Все это будет выглядеть один в один с примером callInOutStructArray . Просто надо внести небольшие изменения, для демонстрации:

1. В Oracle я изменил тип данных первого поля с VARCAHR2 на NUMBER:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
create or replace type rectype as object (
    col1 number( 9 )  -- изменено
 
  , col2 varchar2( 10  char)  -- чтобы русские символы при UTF8 умещались
 
);
/
...
create or replace package body ioStructArray as
procedure testproc(iorec in out rectab, orec out rectab) is
begin
  orec := iorec;
  for i in  1 ..iorec.count loop
    iorec(i).col1 := orec(i).col1;   -- изменено, ибо не всегда с VARCAHR2 в NUMBER переводим
 
    iorec(i).col2 := orec(i).col2;
  end loop;
end testproc;
end ioStructArray;
/


2. В Java меняем пару строк, вместо записи из строк передаем запись из числа и строки:

Код: plaintext
1.
2.
      Object [] p1recobj = { "FIRST" , "LAST" };
      Object [] p2recobj = { "SECOND" , "LAST" };


меняем на
Код: plaintext
1.
2.
    Object[] p1recobj = {new Integer( 1 ),  "Первый" };
    Object[] p2recobj = {new Integer( 2 ),  "Второй" };


И все, запускаем.
...
Рейтинг: 0 / 0
Передача ARRAY в хранимую процедуру Oracle
    #32417398
spainard
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Спасибо Денис, попробуем.
...
Рейтинг: 0 / 0
Передача ARRAY в хранимую процедуру Oracle
    #32417412
spainard
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Тока в Java по моему не совсем так,.. мы ведь должны передовать массив, состоящий из объектов int и String.
Это будет Object[][] ob= {{new Integer(1), "Первый"}, {new Integer(2), "Второй"}};

Если я правильно понимаю?
...
Рейтинг: 0 / 0
Передача ARRAY в хранимую процедуру Oracle
    #32417480
Фотография Denis Popov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В конечном итоге - да. Может быть можно атаптировать вышеуказанный код до такой степени, чтобы сразу создавать "массив массивов". Просто я попытался показать миминум требуемых измененений кода для демонстрации его способности к загрузке массивов, содержащих некий другой тип данных.
...
Рейтинг: 0 / 0
Передача ARRAY в хранимую процедуру Oracle
    #32422037
spainard
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Спасибо Денис.
Но вызвать процедуру таким способом не удается :(
Как мне тогда правильно передавать созданный объект
Попробовал setObject:

Код: plaintext
1.
2.
3.
4.
5.
6.
OracleCallableStatement cstmt = (OracleCallableStatement)con.prepareCall( "{call MySch.Test(?)}" );

Object[][] ob= {{new String( "hello" ), new Integer( 1 ), new Float( 1 . 5 )}};
System.out.println( "1 ");
cstmt.setObject( 1 ,ob);
System.out.println( "2 ");
cstmt.execute();


Выдает ошибку 17049 на setObject
Попробовал по другому:
Код: plaintext
1.
2.
3.
4.
5.
oracle.sql.StructDescriptor qq=new oracle.sql.StructDescriptor( "TRECORD" , con);

Object[][] ob= {{new String( "kdhfgkfd" ), new Integer( 1 ), new Float( 1 . 5 )}};
System.out.println( "11 ");
oracle.sql.STRUCT ww =  new oracle.sql.STRUCT(qq, con, ob);
System.out.println( "22 ");

Пишет java ? sql 17049 (на oracle.sql.STRUCT ww...)
Тоже не правильно.
Хелп, плиз.
...
Рейтинг: 0 / 0
Передача ARRAY в хранимую процедуру Oracle
    #32422091
spainard
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Немного изменил передаваемый объект (теперь [], а не [][])
Код: plaintext
1.
2.
3.
    Object[] ob= {new String( "kdhfgkfd" ), new Integer( 1 ), new Float( 1 . 5 )};
     System.out.println( "11 ");
     oracle.sql.STRUCT ww =  new oracle.sql.STRUCT(qq, con, ob);
     System.out.println( "22 ");


Ошибка java ? sql 17049 изчезла, но вылезла та старая:
oracle-character-set-171 17056
которая была и при передаче просто ARRAY типа varchar.

код 171 соответствует кодировке cl8mswin1251, а 17056 - ошибка "Non supported character set"
Получается, что мой драйвер не порддерживает эту кодировку!?
Это довольно странно..
Что же делать?
...
Рейтинг: 0 / 0
Передача ARRAY в хранимую процедуру Oracle
    #32422274
Фотография Denis Popov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Напиши мне письмо, адрес в профиле, я свой пример покажу.
...
Рейтинг: 0 / 0
Передача ARRAY в хранимую процедуру Oracle
    #32876140
kaka
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
столкнулся с такой же проблемой
oracle-character-set-171 Unsupported charset

скажите как вы ее все таки победили ?
...
Рейтинг: 0 / 0
Передача ARRAY в хранимую процедуру Oracle
    #32876970
Фотография Denis Popov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
Передача ARRAY в хранимую процедуру Oracle
    #32888758
Ctrl+Alt+Delete
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
таже проблема !

имею:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
CREATE OR REPLACE TYPE  t_struct_string AS OBJECT
(
  id1 INTEGER,
  title nvarchar2( 100 )
)
/

CREATE OR REPLACE type var_struct_string is table of t_struct_string;
/


Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
Object[] obj1 = { new  Integer( 1 ), "aaaa"};  
Object[] obj2 = { new  Integer( 2 ), "bbbb"}; 
Object[] obj3 = { new  Integer( 3 ), "cccc"};                 
oracle.sql.StructDescriptor sq = oracle.sql.StructDescriptor.createDescriptor("INDEED.T_STRUCT_STRING", conn);
oracle.sql.STRUCT struct1 =   new  oracle.sql.STRUCT(sq, conn, obj1);
oracle.sql.STRUCT struct2 =   new  oracle.sql.STRUCT(sq, conn, obj2);
oracle.sql.STRUCT struct3 =   new  oracle.sql.STRUCT(sq, conn, obj3);    
               
Object[] a = {struct1,struct2,struct3};                
oracle.sql.ArrayDescriptor ad = oracle.sql.ArrayDescriptor.createDescriptor("INDEED.VAR_STRUCT_STRING", conn); 
oracle.sql.ARRAY array =  new  oracle.sql.ARRAY(ad, elements.getConnection(), a); 
cstm = (OracleCallableStatement)conn.prepareCall("{ call p_test.settemp_struct_string(?) }");
cstm.setArray( 1 , array); 
cstm.execute();

в classpath прописан nls_charset12.jar


и все равно ошибка: oracle-character-set-171 Unsupported charset

кто поборол ?
...
Рейтинг: 0 / 0
Передача ARRAY в хранимую процедуру Oracle
    #32889181
Фотография Timm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А если zip вместо jar?
...
Рейтинг: 0 / 0
Передача ARRAY в хранимую процедуру Oracle
    #32889265
mitya
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не знаю, но может это вам как-то поможет.

У меня при передача ARRAY в хранимую процедуру Oracle
возникала ошибка:

Invocation exception: Cannot map Unicode to Oracle character.(java.sql.SQLException: Cannot map Unicode to Oracle character.)
java.sql.SQLException: Cannot map Unicode to Oracle character.
at oracle.sql.converter.CharacterConverter1Byte.toOracleCharacter(CharacterConverter1Byte.java:156)
at oracle.sql.converter.CharacterConverter1Byte.toOracleString(CharacterConverter1Byte.java:246)
at oracle.sql.CharacterSetWithConverter.convert(CharacterSetWithConverter.java:160)
at oracle.sql.CHAR.(CHAR.java:133)
at oracle.sql.CHAR.(CHAR.java:157)
at oracle.jdbc.oracore.OracleTypeCHAR.toDatum(OracleTypeCHAR.java:145)
at oracle.jdbc.oracore.OracleType.toDatumArray(OracleType.java:145)
at oracle.jdbc.oracore.OracleTypeCHAR.toDatumArray(OracleTypeCHAR.java:173)
at oracle.sql.ArrayDescriptor.toOracleArray(ArrayDescriptor.java:768)
at oracle.sql.ARRAY.(ARRAY.java:118)

Я убил много времени, но поборол это так:

необходимо было переконвертить строки в ARRAY в Cp1250:

if(rowI.get(indIC) != null)
cValuesS[i-1] = new String(((String)rowI.get(indIC)).getBytes("Cp1250"), "Cp1250");
else
cValuesS[i-1] = (String)rowI.get(indIC);
......
.....
oracle.sql.ArrayDescriptor arrayDesc = oracle.sql.ArrayDescriptor.createDescriptor("EDBADM.STRING_VARRAY", db_con.getMetaData().getConnection());
......
oracle.sql.ARRAY arrayc = new oracle.sql.ARRAY(arrayDesc, db_con.getMetaData().getConnection(), cValuesS);
...
Рейтинг: 0 / 0
Передача ARRAY в хранимую процедуру Oracle
    #32890139
Ctrl+Alt+Delete
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
неа ... не помогло ;-(
...
Рейтинг: 0 / 0
Передача ARRAY в хранимую процедуру Oracle
    #33046178
GuestYork
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Решили проблему с русским языком скачиванием какой-то новой версии дров. В этой версии nls_charset12.jar имеет размер 5000574 байт
...
Рейтинг: 0 / 0
Передача ARRAY в хранимую процедуру Oracle
    #33186720
bolgare
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
а где вы эти дрова взяли не подскажите?
...
Рейтинг: 0 / 0
25 сообщений из 25, страница 1 из 1
Форумы / Java [игнор отключен] [закрыт для гостей] / Передача ARRAY в хранимую процедуру Oracle
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]