【问题标题】:Why does JDBC driver pad some blank characterS other a queried field, from an Oracle Database?为什么 JDBC 驱动程序在 Oracle 数据库中填充查询字段以外的一些空白字符?
【发布时间】:2010-12-27 04:14:08
【问题描述】:

所以,这里是在 Oracle 10g / UTF-8 数据库中创建表的代码:

CREATE TABLE TEST_SEMANTIC
(
SEMANTIC_COLBYTE char(2 byte) ,
SEMANTIC_COLCHAR char(2 char)
);

意思是,我对两列使用两种不同类型的语义,字节和字符。

然后我在数据库中插入这些相应的数据:

insert into test_semantic(SEMANTIC_COLBYTE,SEMANTIC_COLCHAR)
values('é','é');

所以当我使用 JDBC 驱动程序在 java 程序中查询数据库并显示结果时,我希望得到这样的输出:

Byte>é<
Char>é<

虽然我得到了这个:

Byte>é<
Char>é      <

当我这样查询数据库时:

select dump(semantic_colbyte,16),dump(semantic_colchar,16) from test_semantic;

我明白了:

Typ=96 Len=2: c3,a9 Typ=96 Len=3: c3,a9,20

这里是java代码:

public static void main(String[] args){
        Connection con = null;
        try {
            Class.forName("oracle.jdbc.driver.OracleDriver");

        } catch (java.lang.ClassNotFoundException e) {
            System.err.print("ClassNotFoundException:");
            System.err.println(e.getMessage());
        }

        try {
            Properties props = new Properties();
            props.put("user", "XXX");
            props.put("password", "XXX");

            con = DriverManager.getConnection("jdbc:oracle:thin:@xxx:1521:xxx", props);
            Statement stmt = (Statement) con.createStatement();
            stmt.execute("SELECT SEMANTIC_COLBYTE,SEMANTIC_COLCHAR FROM TEST_SEMANTIC"); 
            ResultSet result = stmt.getResultSet();
            result.next();
            String output_byte = result.getString(1);
            String output_char = result.getString(2);

        System.out.println("Byte>"+output_byte+"<");                
        System.out.println("Char>"+output_char+"<");

        } catch (SQLException ex) {
            System.err.println("SQLException: " + ex.getMessage());
        }
    }

【问题讨论】:

  • 好的,问题出在驱动,ojdbc14.jar ==> 当使用这个时我得到>é éé

标签: java database oracle utf-8 jdbc


【解决方案1】:

CHAR Datatype:

CHAR 数据类型指定一个固定长度的字符串。 Oracle 确保存储在 CHAR 列中的所有值都具有由 size 指定的长度。如果您插入的值比列长度短,Oracle 会将值填充为列长度。

【讨论】:

    【解决方案2】:

    在使用char 时不要忘记trim 您的价值观。或者不要使用char,使用varchar2,直到您提供精确大小的值作为列大小。

    您可能想知道原因,so here it is

    【讨论】:

    • 感谢您的回答和链接。实际上,我知道 char 和 varchar2 之间的区别。而我存储在数据库中的相应字符串不是变量,而是在 2 个字符上预定义的,而是在 UTF-8 语义中(在 Oracle 下)。更准确地说,我的问题是:通过知道转换非 ascii char(fr.wikipedia.org/wiki/UTF-8) 的 UTF-8 规则,为什么我的 java 程序至少没有给我:>é é
    • 啊!我明白你的意思了。我为我的误会道歉。该值实际上来自驱动程序。所以,这就是驱动程序实现它的方式。不能做太多,修剪价值是你最好的选择。
    • 顺便说一句,您的 SQL 客户端也是基于 Java 的吗?
    • 是的,据我所知,SqlDeveloper 是基于 java 的,但我不知道它使用的是哪个驱动程序。
    • 你用的是什么罐子?试试 ojdbc5 或 ojdbc6。或者,如果没有任何效果,那么您可能想尝试 OCI 驱动程序。我想 SQL Developer 使用的是相同的,因为他们为 SQL Developer 提供特定于平台的下载,而 OCI 适合独立应用程序。
    【解决方案3】:

    您是否已阅读有关字符数据类型的 Oracle 长度语义的 Oracle 文档?

    http://download.oracle.com/docs/cd/B19306_01/server.102/b14220/datatype.htm#sthref3787

    【讨论】:

    • 是的,当然,在我看来,我的问题暗示了对Oracle长度语义的理解。
    • 刚刚签到,其他发现此问题以寻找他们所遇到问题的答案的人可能没有阅读它。
    【解决方案4】:

    数据库(和您的会话)实际在哪个字符集中。 我的是 AL32UTF8 并且不接受 2 字节 CHAR 字段中的“é”。 在一个 4 字节的字段中,它转到 Typ=96 Len=4: ef,bf,bd,20

    一个 UTF-8 字符可以是四个字节,因此 CHAR(2 char) 最多可以是八个字节。所以我可以理解一个长度为 8 的字符串出来。七有点奇怪,就像被告知第一个字符是三个字节,第二个字符最多可以是四个一样。

    你能用ResultSetMetaData(例如getColumnDisplaySize、getColumnTypeName)看看结果吗?

    【讨论】:

    • 不是七个字节 - 七个字符。 é 将是两个字节。剩下的 6 个字节是填充 - 每个空格字符占用一个字节。不过,鉴于转储函数仅显示 3 个字节,这看起来确实像 Vinegar 所建议的 JDBC 驱动程序的问题。
    • 不知道你是怎么到 ef bf bd 的。那是 U+FFFD,未知或无法表示的字符的替换字符。
    • 我的数据库是 UTF-8 字符集
    猜你喜欢
    • 2017-04-20
    • 2017-08-15
    • 1970-01-01
    • 1970-01-01
    • 2010-11-30
    • 1970-01-01
    • 1970-01-01
    • 2016-12-22
    相关资源
    最近更新 更多