java - Jdbc 数组绑定(bind) : character set encoding

标签 java oracle jdbc character-encoding

我正在尝试将 SQL 字符串数组绑定(bind)到准备好的语句,并且对于某些数据库字符集,数组的值变为空。如果我绑定(bind)简单的字符串(不在数组中),它就可以工作。

如果字符集(v$nls_parameters 中的 NLS_CHARACTERSET)是 AL32UTF8,它工作正常。如果它是 WE8ISO8859P15,那么我可以绑定(bind)字符串,但不能绑定(bind)字符串数组。不同之处似乎在于 Oracle JDBC 有一个 specific list of character set。支持转换,ISO-8859-15 不在其中。

这解释了部分问题,因为当它发现在数据库中时,它会将所有字符串转换为 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();
}

我怀疑我在声明和绑定(bind)数组的方式上做错了什么,但我无法找出是什么。有什么想法吗?

最佳答案

解决方案,以及字符串是否在对象/集合中的区别,is well documented ,实际上:

The basic Java Archive (JAR) files, ojdbc5.jar and ojdbc6.jar, contain all the necessary classes to provide complete globalization support for:

  • Oracle character sets for CHAR, VARCHAR, LONGVARCHAR, or CLOB data that is not being retrieved or inserted as a data member of an Oracle object or collection type.
  • CHAR or VARCHAR data members of object and collection for the character sets US7ASCII, WE8DEC, WE8ISO8859P1, WE8MSWIN1252, and UTF8.

To use any other character sets in CHAR or VARCHAR data members of objects or collections, you must include orai18n.jar in the CLASSPATH environment variable of your application.

在CLASSPATH中添加orai18n.jar后,效果非常好

关于java - Jdbc 数组绑定(bind) : character set encoding,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10435950/

相关文章:

java - 是否有一个 Java 库可以将 Olsen 时区 id 转换为 Windows 时区 id

java - logback如何监视配置文件

java - 甲骨文 JDBC : How to know which row throws unique key constraint?

sql - 将重复记录移动到不同的表

java - JXLS - 如何在工作簿中创建指向 Excel 工作表的超链接

sql - 用Sql计算酒店的峰值容量

java - 使用 MySQL 数据库语法错误填充 jTable

postgresql - jOOQ 时间戳与本地时区偏移一起存储

java - 我有 mysql 连接问题,尽管我使用相同的参数连接到命令行

java - 用于调试和测试的 Log4j 配置