powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / Проблема приема массива из Oracle
16 сообщений из 16, страница 1 из 1
Проблема приема массива из Oracle
    #38037896
Всем привет! Столкнулся с проблемой приема массива из Oracle (out параметр процедуры) в Java.

У меня используются три типа T_REC,T_NUMBER1,T_TAB

Код: plsql
1.
2.
3.
4.
5.
6.
CREATE OR REPLACE 
TYPE t_rec                                                                                                                                                                                                                            IS OBJECT
  (  num    NUMBER(8)
  ,  val   VARCHAR2(255)
  )
/



Типы T_NUMBER1 и T_TAB это таблицы типов NUMBER и T_REC соответственно.

Взято из примера Дениса Попова, но переделал под свой случай!

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
public class CallableStructArray {
    //Прописываем все необходимое для коннекта к базе
  private static final String username = "CS_TEST";
  private static final String password = "CS_TEST";
  private static final String URL = "jdbc:oracle:thin:@<host>:<port>:<SERVICE_NAME>";
  
  public static void main(String[] args)
    throws SQLException {
    DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
    // Коннект к Oracle.
    Connection con = DriverManager.getConnection(URL, username, password);
    // Определяем два дескриптора, для ARRAY TYPE и для OBJECT TYPE.

    ArrayDescriptor  arrayDescNum = ArrayDescriptor.createDescriptor("T_NUMBER1", con);
  
    StructDescriptor structDescVar = StructDescriptor.createDescriptor("T_REC", con);
    ArrayDescriptor  arrayDescVar = ArrayDescriptor.createDescriptor("T_TAB", con);
   
    // Инициализация коллекции для объектов STRUCT.
    ArrayList<STRUCT> arrayList = new ArrayList<STRUCT>();
    
    ArrayList v_array = new ArrayList();
    
    // Объявление массива для значений.
    // Размерность его равна количеству атрибутов в объектном типе T_TAB,
    // присвоение значений будет идти в порядке объявления в объектном типе.
    Object[] record = new Object[2];
    // Определение значений и создание объекта STRUCT.
    record[0] = 1;
    record[1] = "Val";
    arrayList.add(new STRUCT(structDescVar, con, record));
    
    ARRAY parrayDVS_ID = new ARRAY(arrayDescNum, con, v_array.toArray());
    ARRAY parrayVAL_TYPE = new ARRAY(arrayDescVar, con, arrayList.toArray());
    ARRAY parrayFUNC_VSN = new ARRAY(arrayDescVar, con, arrayList.toArray());
    ARRAY parrayFUNC_STR = new ARRAY(arrayDescVar, con, arrayList.toArray());
    ARRAY parrayFUNC_ALL = new ARRAY(arrayDescVar, con, arrayList.toArray());
    ARRAY parrayLCHAR = new ARRAY(arrayDescVar, con, arrayList.toArray());
    ARRAY parrayRCHAR = new ARRAY(arrayDescVar, con, arrayList.toArray());

    OracleCallableStatement cst = (OracleCallableStatement) con.prepareCall(
      "{CALL ap_valdiv.parsehiststringoutfour(p_mlt_id=>?, p_clf_id=>?, p_cls_id=>?, p_prj_id=>?, p_string=>?, p_dvs_id=>?, p_val_type=>?,p_func_vsn=>?,p_func_str=>?,p_func_all=>?,p_lchar=>?,p_rchar=>?) }"
    );
    cst.setInt(1, 1);
    cst.setInt(2, 6);
    cst.setInt(3, 60386);
    cst.setInt(4, 0 );
    cst.setString(5, "<lower(valsgn)>{[2]}{[3]}{[14]}{[15]}{[19]}{[26]}{[27]}{[30]}{[31]}{[33]}");
    cst.registerOutParameter(6, OracleTypes.ARRAY,"T_NUMBER1");//здесь задаются параметры процедуры
    cst.setARRAY(6,parrayDVS_ID);
    cst.registerOutParameter(7, OracleTypes.ARRAY,"T_TAB");//здесь задаются параметры процедуры
    cst.setARRAY(7,parrayVAL_TYPE);
    cst.registerOutParameter(8, OracleTypes.ARRAY,"T_TAB");//здесь задаются параметры процедуры
    cst.setARRAY(8,parrayFUNC_VSN);
    cst.registerOutParameter(9, OracleTypes.ARRAY,"T_TAB");//здесь задаются параметры процедуры
    cst.setARRAY(9,parrayFUNC_STR);
    cst.registerOutParameter(10, OracleTypes.ARRAY,"T_TAB");//здесь задаются параметры процедуры
    cst.setARRAY(10,parrayFUNC_ALL);
    cst.registerOutParameter(11, OracleTypes.ARRAY,"T_TAB");//здесь задаются параметры процедуры
    cst.setARRAY(11,parrayLCHAR);
    cst.registerOutParameter(12, OracleTypes.ARRAY,"T_TAB");//здесь задаются параметры процедуры
    cst.setARRAY(12,parrayRCHAR);
    cst.execute();
    
    parrayDVS_ID = cst.getARRAY(6);
    parrayVAL_TYPE = cst.getARRAY(7);
    parrayFUNC_VSN = cst.getARRAY(8);
    parrayFUNC_STR = cst.getARRAY(9);
    parrayFUNC_ALL = cst.getARRAY(10);
    parrayLCHAR = cst.getARRAY(11);
    parrayRCHAR = cst.getARRAY(12);
    
    Object[] pDVS_ID = (Object[]) parrayDVS_ID.getArray();
    Object[] pVAL_TYPE = (Object[]) parrayVAL_TYPE.getArray();
    Object[] pFUNC_VSN = (Object[]) parrayFUNC_VSN.getArray();
    Object[] pFUNC_STR = (Object[]) parrayFUNC_STR.getArray();
    Object[] pFUNC_ALL = (Object[]) parrayFUNC_ALL.getArray();
    Object[] pLCHAR = (Object[]) parrayLCHAR.getArray();
    Object[] pRCHAR = (Object[]) parrayRCHAR.getArray();
    
    Object[] pRecord = new Object[2];
    // Альтернативный метод получения параметра в случае возни с кодировками
    System.out.println("\nВторой объект через Datum:");
    Datum[] datum = parrayFUNC_ALL.getOracleArray();
    for (Datum aDatum : datum) {
      Datum[] rec = ((STRUCT) aDatum).getOracleAttributes();
      if ((rec[0] != null) && (rec[1]!=null))
        System.out.println(rec[0].intValue() + " | " + rec[1].stringValue());
    }
    
    System.out.println("Первый объект:");
    for (int i = 0; i < pDVS_ID.length; i++) {
            System.out.println("pDVS_ID "+pDVS_ID[i]);
            pRecord = ((STRUCT) pFUNC_ALL[i]).getAttributes();
            System.out.println("  pRecord "+pRecord[0]+" | "+pRecord[1]);
    }
        
    System.out.println();
  }
}



Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
PROCEDURE parsehiststringoutfour (p_mlt_id         NUMBER,
                                  p_clf_id         NUMBER,
                                  p_cls_id         NUMBER,
                                  p_prj_id         NUMBER,
                                  p_string         VARCHAR2:= NULL,
                                  p_dvs_id     OUT t_number1,
                                  p_val_type   OUT t_tab,
                                  p_func_vsn   OUT t_tab,
                                  p_func_str   OUT t_tab,
                                  p_func_all   OUT t_tab,
                                  p_lchar      OUT t_tab,
                                  p_rchar      OUT t_tab)



Теперь собственно проблема, при работе с полученными массивами у меня вместо текста у p_func_all выводится просто "???". Т.е. любое текстовое значение выводится как "???". Такая проблема с типом T_TAB. У T_NUMBER1 все нормально p_dvs_id выводится нужный.

При выполнении процедуры в базе там все нормально выводится, текст какой и должен быть.

Вопрос как получать правильные значения типа VARCHAR2?

Просто пробовал заменять тип T_TAB, на T_VARCHAR2 (таблица VARCHAR2), разницы никакой, все теже "???"

Что это, проблема с кодировкой? Что то в джаве надо дописать? Использую netbeans...
Помогите кто, чем может...
...
Рейтинг: 0 / 0
Проблема приема массива из Oracle
    #38038084
rsltr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей LEXUS,

к тоже OUT в процедурах использует
...
Рейтинг: 0 / 0
Проблема приема массива из Oracle
    #38038231
Фотография Denis Popov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей LEXUSЧто это, проблема с кодировкой? Что то в джаве надо дописать? Использую netbeans...
В Oracle JDBC-драйвере 10.2 и 11.2 есть файл orai18n.jar - он подключен к проекту?
...
Рейтинг: 0 / 0
Проблема приема массива из Oracle
    #38038644
На сколько помню именно данный файл не подключен. Вроде только orai06n.jar подключен. Из-за данного файла могут быть проблемы??????
...
Рейтинг: 0 / 0
Проблема приема массива из Oracle
    #38038656
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NLS_LANG ?
...
Рейтинг: 0 / 0
Проблема приема массива из Oracle
    #38038740
Фотография Denis Popov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей LEXUSНа сколько помню именно данный файл не подключен. Вроде только orai06n.jar подключен. Из-за данного файла могут быть проблемы??????
без него у меня в консоли тоже одни вопросы:
+
CallableStructArray.java
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
import oracle.jdbc.OracleCallableStatement;
import oracle.jdbc.OracleTypes;
import oracle.sql.ARRAY;
import oracle.sql.Datum;
import oracle.sql.STRUCT;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;

public class CallableStructArray {
  private static final String username = "scott";
  private static final String password = "tiger";
  private static final String URL = "jdbc:oracle:thin:@127.0.0.1:1521/RAM";

  public static void main(String[] args)
    throws SQLException {
    DriverManager.registerDriver(new oracle.jdbc.OracleDriver());
    Connection con = DriverManager.getConnection(URL, username, password);
    Statement st = con.createStatement();
    try { st.execute("drop type t_tab force"); } catch (SQLException e) { }
    st.execute("create or replace type T_REC is object (num number(8), val varchar2(255))");
    st.execute("create or replace type T_TAB as table of T_REC");

    st.execute(
      "create or replace procedure TEST_TAB (p_string varchar2, p_tab out t_tab) as\n" +
      "  cr sys_refcursor;\n" +
      "  vt sys.odciVarchar2List;\n" +
      "begin\n" +
      "  open cr for 'select sys.odciVarchar2List('''||replace(p_string, ',', ''',''')||''') from DUAL';\n" +
      "  fetch cr into vt;\n" +
      "  p_tab := t_TAB();\n" +
      "  for i in vt.first .. vt.last loop\n" +
      "    p_tab.extend();\n" +
      "    p_tab(p_tab.last) := T_REC(i, vt(i));\n" +
      "    dbms_output.put_line(i||': '||vt(i));\n" +
      "  end loop;\n" +
      "end;"
    );

    OracleCallableStatement cst = (OracleCallableStatement) con.prepareCall(
      "{call TEST_TAB(p_string => ?, p_tab => ?)}"
    );

    String value = "Один,Два,Три,Четыре,Пять";
    System.out.println(value);

    cst.setString(1, value);
    cst.registerOutParameter(2, OracleTypes.ARRAY, "T_TAB");
    cst.execute();

    ARRAY array = cst.getARRAY(2);

    Datum[] datum = array.getOracleArray();
    for (Datum aDatum : datum) {
      Datum[] rec = ((STRUCT) aDatum).getOracleAttributes();
      if ((rec[0] != null) && (rec[1] != null)) { System.out.println(rec[0].intValue() + " | " + rec[1].stringValue()); }
    }
    cst.close();
    con.close();
  }
}



Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
C:\Tmp>chcp 1251
Active code page: 1251

C:\Tmp>java -classpath .;C:\Oracle\ora11\jdbc\lib\ojdbc6.jar CallableStructArray
Один,Два,Три,Четыре,Пять
1 | ???
2 | ???
3 | ???
4 | ???
5 | ???

C:\Tmp>java -classpath .;C:\Oracle\ora11\jdbc\lib\ojdbc6.jar;C:\Oracle\ora11\jlib\orai18n.jar CallableStructArray
Один,Два,Три,Четыре,Пять
1 | Один
2 | Два
3 | Три
4 | Четыре
5 | Пять
...
Рейтинг: 0 / 0
Проблема приема массива из Oracle
    #38039111
Сейчас вообще непонятное творится. При добавлении библиотеки orai18n.jar перестал создаваться Connection.

Выдает следующую ошибку

авторException in thread "main" java.lang.NoSuchMethodError: oracle.i18n.text.converter.CharacterConverterOGS.getInstance(I)Loracle/i18n/text/converter/CharacterConverter;
at oracle.sql.converter.CharacterConverterFactoryOGS.make(CharacterConverterFactoryOGS.java:43)
at oracle.sql.CharacterSetWithConverter.getInstance(CharacterSetWithConverter.java:95)
at oracle.sql.CharacterSetFactoryThin.make(CharacterSetFactoryThin.java:126)
at oracle.sql.CharacterSet.make(CharacterSet.java:450)
at oracle.jdbc.driver.DBConversion.init(DBConversion.java:151)
at oracle.jdbc.driver.DBConversion.<init>(DBConversion.java:112)
at oracle.jdbc.driver.T4CConnection.connect(T4CConnection.java:1075)
at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:301)
at oracle.jdbc.driver.PhysicalConnection.<init>(PhysicalConnection.java:531)
at oracle.jdbc.driver.T4CConnection.<init>(T4CConnection.java:221)
at oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.java:32)
at oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:503)
at java.sql.DriverManager.getConnection(DriverManager.java:579)
at java.sql.DriverManager.getConnection(DriverManager.java:221)
at contooracle.CallableStructArray.main(CallableStructArray.java:38)

Если библиотеку убрать, оставить только ojdbc6.jar, то по прежнему выводятся вопросы вместо текста.

Чудеса прям(((
...
Рейтинг: 0 / 0
Проблема приема массива из Oracle
    #38039115
Забыл сказать Денис, тоже самое если выполнить приведенный выше новый код класса CallableStructArray.

Только у меня свои настройки подключения

Код: java
1.
2.
3.
private static final String username = "CS_TEST";
private static final String password = "CS_TEST";
private static final String URL = "jdbc:oracle:thin:@ORA5:1521:orcl";



База 10.2.
...
Рейтинг: 0 / 0
Проблема приема массива из Oracle
    #38039120
Фотография Denis Popov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
On 15.11.2012 08:43, Алексей LEXUS wrote:

> Сейчас вообще непонятное творится. При добавлении библиотеки orai18n.jar перестал создаваться Connection.

Может Быть orai18n.jar и ojdbc6.jar из разных версий jdbc-драйвера, или они берутся из одного ORACLE_HOME? И в какой
кодировке создана сама база?
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Проблема приема массива из Oracle
    #38039121
С файлом ojdbc6.jar не работает ни файл orai18n.jar, ни nls_charset12.jar. выдается та самая ошибка выше.

Но если заменить файл ojdbc6.jar на ojdbc14.jar. То все начинает работать!

Вопрос почему??? И какая разница между ojdbc6.jar и ojdbc14.jar?
...
Рейтинг: 0 / 0
Проблема приема массива из Oracle
    #38039132
ojdbc6.jar оказывается вообще не лежит в директории oracle, он у нас в проекте используется, его походу отдельно скачивали. А ojdbc14.jar лежит в C:\oracle\product\10.2.0\client_1\jdbc\lib.

orai18n.jar лежит в C:\oracle\product\10.2.0\client_1\jlib.

Походу да, ojdbc6.jar и ojdbc14.jar с orai18n.jar из разных версий драйверов. Надо будет согласовать мне замену ojdbc6.jar на ojdbc14.jar.

Денис, спасибо большое!!! Все таки проблема была в нехватке orai18n.jar или nls_charset12.jar.

База с кодировкой CL8MSWIN1251.
...
Рейтинг: 0 / 0
Проблема приема массива из Oracle
    #38039135
Фотография Denis Popov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
On 15.11.2012 09:05, Алексей LEXUS wrote:

> С файлом ojdbc6.jar не работает ни файл orai18n.jar, ни nls_charset12.jar. выдается та самая ошибка выше.
>
> Но если заменить файл ojdbc6.jar на ojdbc14.jar. То все начинает работать!

И русские буквы появились?

> Вопрос почему??? И какая разница между ojdbc6.jar и ojdbc14.jar?

По-моему у тебя они из разных версий драйверов, в 10.1 еще нет ojdbc6.jar:

http://www.oracle.com/technetwork/database/enterprise-edition/jdbc101040-094982.html

а в 11.2 уже нет ojdbc14.jar:

http://www.oracle.com/technetwork/database/enterprise-edition/jdbc-112010-090769.html

А разница в используемой JDK для сборки архива.


Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Проблема приема массива из Oracle
    #38039140
Фотография Denis Popov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
On 15.11.2012 09:27, Алексей LEXUS wrote:

> Надо будет согласовать мне замену ojdbc6.jar на ojdbc14.jar.

Думаю лучше подняться на последнюю версию, т.е. ojdbc6.jar, взяв все необходимое отсюда:

http://www.oracle.com/technetwork/database/enterprise-edition/jdbc-112010-090769.html
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Проблема приема массива из Oracle
    #38039449
Скачал новую версию orai18n.jar, все заработало! Денис, спасибо огромное!
...
Рейтинг: 0 / 0
Проблема приема массива из Oracle
    #38039606
Денис, мучает еще один вопрос. Мы можем обращаться только к глобальным типам, которые описаны в разделе TYPES.

Я пробовал обращаться к типам описанным непосредственно в пакете, но у меня ничего не получилось. Вылетает ошибка и их просто не видно.

Можно ли как-то вызывать процедуры с типами описанными в пакете?
...
Рейтинг: 0 / 0
Проблема приема массива из Oracle
    #38039848
Фотография Denis Popov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
On 15.11.2012 14:09, Алексей LEXUS wrote:

> Можно ли как-то вызывать процедуры с типами описанными в пакете?

Только к скалярным, например, вида TABLE OF NUMBER:

http://docs.oracle.com/cd/E11882_01/java.112/e16548/oraint.htm#JJDBC28182
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
16 сообщений из 16, страница 1 из 1
Форумы / Java [игнор отключен] [закрыт для гостей] / Проблема приема массива из Oracle
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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