2012-05-03 2 views
2

Я пытаюсь привязать массив строк SQL к подготовленному оператору, а для некоторой кодировки базы данных значения массива становятся нулевыми. Если я связываю простые строки (не в массиве), это работает.Связывание массива Jdbc: кодировка набора символов

Если кодировка (NLS_CHARACTERSET в v $ nls_parameters) является AL32UTF8, она работает нормально. Если это WE8ISO8859P15, то я могу привязывать строки, но не массивы строк. Разница, похоже, в том, что Oracle JDBC имеет specific list of character set, для которого поддерживается преобразование, а ISO-8859-15 не является их частью.

Это объясняет часть проблемы, так как когда она обнаруживает, что в БД она преобразует всю строку в нуль. Но преобразование действительно работает, когда строка не находится в массиве ... Поэтому я смущен.

Весь мой тест ниже. Тип таблицы я использую определяется как create type t_v4000_table as table of varchar2(4000);

Connection connection; 

@Before 
public void setup() throws SQLException { 
    OracleDataSource ds = new OracleDataSource(); 
    ds.setUser("aaa"); 
    ds.setPassword("a"); 
    ds.setURL("jdbc:oracle:thin:@server:1521:orcl"); 
    connection = ds.getConnection(); 
} 

@Test 
// works with both AL32UTF8 and WE8ISO8859P15 
public void testScalar() throws SQLException { 
    CallableStatement stmt = connection.prepareCall("declare a varchar2(4000) := ?; " 
      + "begin if a is null then raise_application_error(-20000,'null'); end if; end;"); 
    stmt.setString(1, "a"); 
    stmt.execute(); 
} 

@Test 
// works only with AL32UTF8 
public void testArray() throws SQLException { 
    ArrayDescriptor descriptor = ArrayDescriptor.createDescriptor("T_V4000_TABLE", connection); 
    String[] array = new String[] {"a"}; 
    Array sqlArray = new ARRAY(descriptor, connection, array); 
    CallableStatement stmt = connection.prepareCall("declare a t_v4000_table := ?; " + 
      "begin if a(1) is null then raise_application_error(-20000,'null'); end if; end;"); 
    stmt.setArray(1, sqlArray); 
    stmt.execute(); 
} 

Я подозреваю, что я делаю что-то неправильно в том, как я объявляю и связать мой массив, но я не могу выяснить, что. Есть идеи?

+0

Это уже вопрос: 'создать тип t_v4000_table в таблице varchar2 (4000),' – Xavier

+0

Если я изменить его к столу nvarchar2 (4000), тестовый проход, но это потому, что NLS_NCHAR_CHARACTERSET - это AL16UTF16 в экземпляре, который поддерживается Oracle JDBC. Поэтому я только перемещаю проблему в другом месте ... – Xavier

ответ

3

Решение, а также различие между строкой внутри объектов/коллекций или нет, is well documented, на самом деле:

Основные Java Archive (JAR) файлов, ojdbc5.jar и ojdbc6.jar, содержат все необходимые классы, чтобы обеспечить полную поддержку глобализации для:

  • Oracle символьных наборов для CHAR, VARCHAR, LONGVARCHAR, или данные CLOB, не будучи извлекаемыми или вставленными в качестве элемента данных объекта или коллекции типа Oracle.
  • Элементы данных CHAR или VARCHAR для набора символов US7ASCII, WE8DEC, WE8ISO8859P1, WE8MSWIN1252 и UTF8.

Чтобы использовать любые другие наборы символов в элементах или коллекциях данных CHAR или VARCHAR, вы должны включить orai18n.jar в переменную среды CLASSPATH вашего приложения.

После добавления orai18n.jar в CLASSPATH, он работает как шарм

Смежные вопросы