Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Java [игнор отключен] [закрыт для гостей] / FAQ: Java & Oracle, передача-прием массивов. / 18 сообщений из 18, страница 1 из 1
19.01.2005, 14:37
    #32872455
Denis Popov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
FAQ: Java & Oracle, передача-прием массивов.
Взято с Metalink .

При работе через THIN-драйвер отсутствует возможность передачи -приема pl/sql таблиц Oracle. Но можно воспользоваться оракловыми объектными типами.

Код, который необходимо выполнить на сттороне Oracle:

Код: plaintext
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.
create or replace type rectype as object (
    cnumber   number ( 9 )
  , cvarchar  varchar2 ( 32  char)
  , cdate     date
)
/
create or replace type rectab as table of rectype;
/
create or replace package iostructarray as
  procedure testproc (
      iorec in out rectab
    , orec out rectab
  );
end;
/
create or replace package body iostructarray as
  procedure testproc (
      iorec in out rectab
    , orec out rectab
  ) is
  begin
    -- Копирование inout параметра в out и изменение inout параметра.
    orec := iorec;
    for i in  1  .. iorec.count loop
      iorec (i).cnumber := -orec (i).cnumber;
      iorec (i).cvarchar := 'New-' || orec (i).cvarchar;
      iorec (i).cdate := orec (i).cdate +  1  +  12  /  24  +  34  / ( 24  *  60 ) +  56  / ( 24  *  60  *  60 );
    end loop;
  end;
end;
/

Демонстрация работы с массивами:

Код: plaintext
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.
 import  oracle.jdbc.driver.OracleCallableStatement;
 import  oracle.jdbc.driver.OracleTypes;
 import  oracle.sql.ARRAY;
 import  oracle.sql.ArrayDescriptor;
 import  oracle.sql.STRUCT;
 import  oracle.sql.StructDescriptor;

 import  java.sql.Connection;
 import  java.sql.DriverManager;
 import  java.sql.SQLException;
 import  java.sql.Timestamp;
 import  java.util.ArrayList;
 import  java.util.Calendar;

 public   class  CallableStructArray {

   private   static   final  String username = "hall";
   private   static   final  String password = "h";
   private   static   final  String URL = "jdbc:oracle:thin:@192.168.170.90:1521:CVPROC";

   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.
    StructDescriptor structDesc = StructDescriptor.createDescriptor("RECTYPE", con);
    ArrayDescriptor arrayDesc = ArrayDescriptor.createDescriptor("RECTAB", con);

    // Инициализация коллекции для объектов STRUCT.
    ArrayList pArrayList =  new  ArrayList();

    // Объявление массива для значений.
    // Размерность его равна количеству атрибутов в объектном типе RECTYPE,
    // присвоение значений будет идти в порядке объявления в объектном типе.
    Object[] pRecord =  new  Object[ 3 ];
    // Определение значений и создание объекта STRUCT.
    pRecord[ 0 ] =  new  Integer( 1 );
    pRecord[ 1 ] = "Первый";
    pRecord[ 2 ] =  new  Timestamp(Calendar.getInstance().getTimeInMillis());
    pArrayList.add( new  STRUCT(structDesc, con, pRecord));

    pRecord[ 0 ] =  new  Integer( 2 );
    pRecord[ 1 ] = "Второй";
    pRecord[ 2 ] =  new  Timestamp(Calendar.getInstance().getTimeInMillis());
    pArrayList.add( new  STRUCT(structDesc, con, pRecord));

    // Создание объекта ARRAY.
    ARRAY pARRAY =  new  ARRAY(arrayDesc, con, pArrayList.toArray());
    // Объявление callable statement.
    // Он должен быть объявлен как OracleCallableStatement.
    OracleCallableStatement cst = (OracleCallableStatement) con.prepareCall(
      "{call ioStructArray.testproc(iorec=>?, orec=>?)}"
    );
    // Определение первого параметра процедуры
    cst.setARRAY( 1 , pARRAY);
    // Первый параметр имеет тип inout, поэтому дополнительно он регистрируется как out.
    // Note the reuse of the TYPE.
    cst.registerOutParameter( 1 , OracleTypes.ARRAY, "RECTAB");
    // Регистрация второго out-параметра процедуры
    cst.registerOutParameter( 2 , OracleTypes.ARRAY, "RECTAB");
    // Выполнение процедуры
    cst.execute();

    // Ассоциация возвращаемого массива с объектом ARRAY.
    pARRAY = cst.getARRAY( 1 );
    // Получение данных первого параметра.
    Object[] pObjects = (Object[]) pARRAY.getArray();
    System.out.println("Первый объект:");
     for  ( int  i =  0 ; i < pObjects.length; i++) {
      pRecord = ((STRUCT) pObjects[i]).getAttributes();
      System.out.println(pRecord[ 0 ] + " | " + pRecord[ 1 ] + " | " + pRecord[ 2 ]);
    }

    // Получение данных второго параметра.
    pARRAY = cst.getARRAY( 2 );
    pObjects = (Object[]) pARRAY.getArray();
    System.out.println("Второй объект:");
     for  ( int  i =  0 ; i < pObjects.length; i++) {
      pRecord = ((STRUCT) pObjects[i]).getAttributes();
      System.out.println(pRecord[ 0 ] + " | " + pRecord[ 1 ] + " | " + pRecord[ 2 ]);
    }
  }
}
...
Рейтинг: 0 / 0
19.01.2005, 16:17
    #32872810
Timm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
FAQ: Java & Oracle, передача-прием массивов.
Можно дополнить и описать использование Custom Object Classes for Oracle Objects (завтра может напишу). Но есть глюк , от которого избавиться не удалось.
...
Рейтинг: 0 / 0
20.01.2005, 11:02
    #32874010
Timm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
FAQ: Java & Oracle, передача-прием массивов.
Пусть имеются вышеописанные типы rectype и rectab.
Код: plaintext
1.
2.
3.
4.
5.
6.
SQL> desc rectab
 rectab TABLE OF RECTYPE
 Name                                                              Null?    Type
 ----------------------------------------------------------------- -------- -----------------
 CNUMBER                                                                    NUMBER( 9 )
 CVARCHAR                                                                   VARCHAR2( 32  CHAR)
 CDATE                                                                      DATE
Для работы с этим типом как с обычным java-классом можно использовать:
1) стандартный интерфейс SQLData;
2) оракловые интерфейсы ORAData и ORADataFactory.
Опишу второй способ.
1) Для генерации java-классов, которые будут представлять оракловые типы, удобно воспользоваться утилитой JPublisher ([ORACLE_HOME]/bin/jbub.exe). Необходимо прописать следующие пути: [ORACLE_HOME]/jdbc/lib/classes12.zip; [ORACLE_HOME]/sqlj/lib/runtime12.zip and [ORACLE_HOME]/sqlj/translator.zip; [ORACLE_HOME]/jdbc/lib/nls_charset12.zip
2) Создаем файл jprop.txt:
jpub.driver=oracle.jdbc.driver.OracleDriver
jpub.numbertypes=oracle
jpub.url=jdbc:oracle:thin:@localhost:1521:info
jpub.builtintypes=oracle
jpub.user=tim/t
jpub.sql=rectab

3) В командной строке:
Код: plaintext
1.
2.
c:\Work\code>jpub -props=jprop.txt
TIM.RECTAB
TIM.RECTYPE
В результате получаем два файла с необходимыми классами: rectab.java и Rectype.java (эстеты могут переименовать классы в RecTab и RecType соответственно:))
4)
Код: plaintext
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.
 import  oracle.jdbc.driver.OracleCallableStatement;
 import  oracle.jdbc.driver.OracleTypes;
 import  oracle.sql.*;

 import  java.sql.*;
 import  java.io.*;
 import  java.util.Calendar;

 public   class  CallableStructArray {

	 private   static   final  String username = "tim";
	 private   static   final  String password = "t";
	 private   static   final  String URL = "jdbc:oracle:thin:@localhost:1521:info";

	 public   static   void  main(String[] args)  throws  SQLException {
		 try  {
			System.setOut( new  PrintStream(System.out, true, "cp866"));
		}  catch  (Exception e) {
		} //try
		DriverManager.registerDriver( new  oracle.jdbc.driver.OracleDriver());
		Connection conn = DriverManager.getConnection(URL, username, password);

		OracleCallableStatement ocstmt = (OracleCallableStatement)conn.prepareCall(
			"BEGIN ioStructArray.testproc(?, ?); END;");

		//get character set
		 int  oracleId = CharacterSet.CL8MSWIN1251_CHARSET;
		CharacterSet myCharSet = CharacterSet.make(oracleId);
		
		//construct array of rectype
		Rectype[] r =  new  Rectype[] {
			 new  Rectype( new  NUMBER( 1 ),  new   CHAR ("Первый", myCharSet),
				 new  DATE( new  Timestamp(Calendar.getInstance().getTimeInMillis()))),
			 new  Rectype( new  NUMBER( 2 ),  new   CHAR ("Второй", myCharSet),
				 new  DATE( new  Timestamp(Calendar.getInstance().getTimeInMillis())))};
		//construct table
		rectab tab =  new  rectab(r);
		
		ocstmt.setORAData( 1 , tab);
		ocstmt.registerOutParameter( 1 , OracleTypes.ARRAY, "RECTAB");
		ocstmt.registerOutParameter( 2 , OracleTypes.ARRAY, "RECTAB");

		ocstmt.execute();

		tab = (rectab)ocstmt.getORAData( 1 , rectab.getORADataFactory());
		r = tab.getArray();
		 for  ( int  i =  0 ; i<r.length; i++) {
			System.out.println(r[i].getCnumber().intValue() + "|" +	r[i].getCvarchar() + "|"
				+ r[i].getCdate().toText("YYYY.MM.DD HH24:MI:SS", "AMERICAN_AMERICA.CL8MSWIN1251"));
		} //for

		tab = (rectab)ocstmt.getORAData( 2 , rectab.getORADataFactory());
		r = tab.getArray();
		 for  ( int  i =  0 ; i<r.length; i++) {
			System.out.println(r[i].getCnumber().intValue() + "|" + r[i].getCvarchar() + "|"
				+ r[i].getCdate().toText("YYYY.MM.DD HH24:MI:SS",  "AMERICAN_AMERICA.CL8MSWIN1251"));
		} //for

	}
};
...
Рейтинг: 0 / 0
24.01.2005, 13:00
    #32879855
Denis Popov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
FAQ: Java & Oracle, передача-прием массивов.
2Timm: я свою часть предложил в разделе FAQ, предложи свою:)
...
Рейтинг: 0 / 0
24.01.2005, 13:10
    #32879885
А.Грасоff™
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
FAQ: Java & Oracle, передача-прием массивов.
Denis Popov2Timm: я свою часть предложил в разделе FAQ, предложи свою:)на всякий: фак опубликован, но, думаю, что не стоит
удалять одноименные топики (как этот, например) из форума -
яндекс и гугл пусть посетителей увеличивают :)
...
Рейтинг: 0 / 0
06.02.2005, 15:40
    #32903035
DrewT
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
FAQ: Java & Oracle, передача-прием массивов.
TimmМожно дополнить и описать использование Custom Object Classes for Oracle Objects (завтра может напишу). Но есть глюк , от которого избавиться не удалось.

От этого глюка избавиться можно, если поставить orai18n.jar и classes12.jar из 10g .
Кроме того, проблемы с выводом русских букв не останется если использовать BLOB, как это показано здесь .
...
Рейтинг: 0 / 0
30.05.2005, 13:42
    #33090617
йцукен
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
FAQ: Java & Oracle, передача-прием массивов.
А подходят ли драйвера от 10g к базам на oracle 8i и 9i. У меня при их использовании вываливается ошибка

ORA-12705: invalid or unknown NLS parameter value specified

хотя установлено

set NLS_LANG=AMERICAN_AMERICA.CL8MSWIN1251
...
Рейтинг: 0 / 0
30.05.2005, 13:53
    #33090648
Denis Popov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
FAQ: Java & Oracle, передача-прием массивов.
йцукенА подходят ли драйвера от 10g к базам на oracle 8i и 9i

У меня после наката пача Oracle 9.2.0.6 перестал работать возврат курсоров из хранимых процедур при использовании JDBC от 10g.
...
Рейтинг: 0 / 0
30.05.2005, 14:02
    #33090687
йцукен
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
FAQ: Java & Oracle, передача-прием массивов.
Denis Popov[У меня после наката пача Oracle 9.2.0.6 перестал работать возврат курсоров из хранимых процедур при использовании JDBC от 10g.

А как ты запустил клиента?
Дело в том, что он у меня вообще не поднимается с этими драйверами.
...
Рейтинг: 0 / 0
30.05.2005, 14:45
    #33090791
Denis Popov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
FAQ: Java & Oracle, передача-прием массивов.
йцукенА как ты запустил клиента?
Дело в том, что он у меня вообще не поднимается с этими драйверами.

Запустил и все:) Ни с какой ошибкой при "запуске" (т.е. при создании соединения?) не столкнулся. М.б. из-за того, что у нас все базы созданы в юникоде, а это порой избавляет от многих проблем.
...
Рейтинг: 0 / 0
30.05.2005, 14:51
    #33090807
йцукен
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
FAQ: Java & Oracle, передача-прием массивов.
Denis Popov[Запустил и все:) Ни с какой ошибкой при "запуске" (т.е. при создании соединения?) не столкнулся. М.б. из-за того, что у нас все базы созданы в юникоде, а это порой избавляет от многих проблем.

Ну тогда конечно, у меня база в 1251
...
Рейтинг: 0 / 0
13.12.2005, 13:13
    #33432838
verter
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
FAQ: Java & Oracle, передача-прием массивов.
Сделал всё по написанному выше:

в java на строчке

pArrayList.add(new STRUCT(structDesc, con, pRecord));

вываливается ошибка:

java.sql.SQLException: Non supported character set: oracle-character-set-171
at oracle.gss.util.NLSError.throwSQLException(NLSError.java:46)
at oracle.sql.CharacterSetUnknown.failCharsetUnknown(CharacterSetFactoryThin.java:171)
at oracle.sql.CharacterSetUnknown.convert(CharacterSetFactoryThin.java:135)
at oracle.sql.CHAR.<init>(CHAR.java:159)
at oracle.sql.CHAR.<init>(CHAR.java:183)
at oracle.jdbc.oracore.OracleTypeCHAR.toDatum(OracleTypeCHAR.java:161)
at oracle.sql.StructDescriptor.toOracleArray(StructDescriptor.java:830)
at oracle.sql.StructDescriptor.toArray(StructDescriptor.java:1735)
at oracle.sql.STRUCT.<init>(STRUCT.java:145)


БД 8.1.7
NLS_NAME = AMERICAN_AMERICA.CL8MSWIN1251

Причём задаю для структуры не русские буквы, английские слова пишу
...
Рейтинг: 0 / 0
13.12.2005, 14:25
    #33433162
Denis Popov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
FAQ: Java & Oracle, передача-прием массивов.
nls_charset12.zip в CLASSPATH есть?
...
Рейтинг: 0 / 0
13.12.2005, 15:58
    #33433540
verter
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
FAQ: Java & Oracle, передача-прием массивов.
Да есть. Я вообще в сервлете всё это делаю, а сервлет запускается на Tomcat'е. Эту библиотеку nls_charset.zip я положил вместе с остальными в Tomcat\common\lib\
...
Рейтинг: 0 / 0
13.12.2005, 16:08
    #33433581
verter
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
FAQ: Java & Oracle, передача-прием массивов.
причём, я посмотрел, что в этой библиотеке nls_charset12.zip есть класс

oracle\sql\converter\CharacterConverter00ab.class

00ab = 171

наверное который работает с этим чарсетом.

после компиляции все библиотеки правильно лежат для Томкэта:

в

%Tomcat%\webapps\Имя_приложения\WEB-INF\lib\

но всё-равно ошибка вылетает.
...
Рейтинг: 0 / 0
13.12.2005, 16:29
    #33433651
Denis Popov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
FAQ: Java & Oracle, передача-прием массивов.
Локально тоже не работает? Что возвращает запрос?
Код: plaintext
select * from sys.props$ where name like 'NLS%CHARACTERSET';
И еще: какой именно используется JDBC-драйвер к Ораклу, имя файла?
...
Рейтинг: 0 / 0
13.12.2005, 16:42
    #33433703
Denis Popov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
FAQ: Java & Oracle, передача-прием массивов.
...
Рейтинг: 0 / 0
13.12.2005, 17:25
    #33433868
verter
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
FAQ: Java & Oracle, передача-прием массивов.
Денис, спасибо за помощь!

решил проблему:

оказывается надо было использовать более свежую nls_charset12.zip, вернее nls_charset12.jar.

Я брал эту библиотеку для 8-ой версии оракла - не работало, взял для 9-ки - всё стало работать.
...
Рейтинг: 0 / 0
Форумы / Java [игнор отключен] [закрыт для гостей] / FAQ: Java & Oracle, передача-прием массивов. / 18 сообщений из 18, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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