SQL 文字列配列を準備済みステートメントにバインドしようとしていますが、一部のデータベース文字セットでは、配列の値が null になります。単純な文字列 (配列ではない) をバインドすると、機能します。
文字セット (v$nls_parameters の NLS_CHARACTERSET) が AL32UTF8 の場合、正常に動作します。WE8ISO8859P15 の場合、文字列をバインドできますが、文字列の配列はバインドできません。違いは、Oracle JDBC には変換がサポートされている文字セットの特定のリストがあり、ISO-8859-15 はそれらの一部ではないことです。
DBでそれが見つかった場合、すべての文字列をnullに変換するため、これが問題の一部を説明しています。しかし、文字列が配列にない場合、変換は機能します...だから私は混乱しています。
私の全体のテストは以下のとおりです。私が使用しているテーブルタイプは次のように定義されています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();
}
配列を宣言してバインドする方法に何か問題があると思われますが、何が原因かわかりません。何か案が?