Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/399.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么JDBC驱动程序会在Oracle数据库的查询字段之外填充一些空白字符?_Java_Database_Oracle_Utf 8_Jdbc - Fatal编程技术网

Java 为什么JDBC驱动程序会在Oracle数据库的查询字段之外填充一些空白字符?

Java 为什么JDBC驱动程序会在Oracle数据库的查询字段之外填充一些空白字符?,java,database,oracle,utf-8,jdbc,Java,Database,Oracle,Utf 8,Jdbc,下面是在Oracle 10g/UTF-8数据库中创建表的代码: CREATE TABLE TEST_SEMANTIC ( SEMANTIC_COLBYTE char(2 byte) , SEMANTIC_COLCHAR char(2 char) ); 也就是说,我对这两列使用了两种不同类型的语义,byte和char 然后,我在数据库中插入这些相应的数据: insert into test_semantic(SEMANTIC_COLBYTE,SEMANTIC_COLCHAR) values('é

下面是在Oracle 10g/UTF-8数据库中创建表的代码:

CREATE TABLE TEST_SEMANTIC
(
SEMANTIC_COLBYTE char(2 byte) ,
SEMANTIC_COLCHAR char(2 char)
);
也就是说,我对这两列使用了两种不同类型的语义,byte和char

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

insert into test_semantic(SEMANTIC_COLBYTE,SEMANTIC_COLCHAR)
values('é','é');
因此,当我使用JDBC驱动程序在java程序中查询数据库并显示结果时,我希望得到如下输出:

Byte>é<
Char>é<
select dump(semantic_colbyte,16),dump(semantic_colchar,16) from test_semantic;
我明白了:

Byte>é<
Char>é      <
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());
        }
    }
publicstaticvoidmain(字符串[]args){
连接con=null;
试一试{
类forName(“oracle.jdbc.driver.OracleDriver”);
}catch(java.lang.ClassNotFoundException){
System.err.print(“ClassNotFoundException:”);
System.err.println(e.getMessage());
}
试一试{
Properties props=新属性();
道具放置(“用户”、“XXX”);
道具放置(“密码”、“XXX”);
con=DriverManager.getConnection(“jdbc:oracle:thin:@xxx:1521:xxx”,props);
语句stmt=(语句)con.createStatement();
stmt.execute(“从TEST_SEMANTIC中选择SEMANTIC_COLBYTE,SEMANTIC_COLCHAR”);
ResultSet result=stmt.getResultSet();
result.next();
String output_byte=result.getString(1);
字符串输出\u char=result.getString(2);

System.out.println(“Byte>”+output\u Byte+“+output\u char+”在使用
char
时,不要忘记
trim
您的值。或者不要使用
char
,使用
varchar2
,直到您提供精确的大小值作为列大小

您可能想知道原因。

CHAR数据类型指定一个固定长度的字符串。Oracle确保存储在CHAR列中的所有值都具有大小指定的长度。如果插入的值短于列长度,则Oracle blank会将该值填充到列长度


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


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

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


您可以使用ResultSetMetaData(例如getColumnDisplaySize、getColumnTypeName)并查看结果。

谢谢您的回答和链接。实际上,我知道char和varchar2之间的区别。我存储在数据库中的对应字符串不是变量,而是在2个字符上预定义的,而是在UTF-8语义(Oracle下)中预定义的。更准确地说,我的问题是:通过了解转换非ascii字符()的UTF-8规则,为什么我的java程序不给我至少一个:>é<和一个空白字符(例如,我通过使用SQLDeveloper查询数据库得到的输出),但是给我>é<6空格?啊!我明白你的意思了。很抱歉误解。值实际上来自驱动程序。所以,驱动程序就是这样实现的。做的不多,修剪值是你最好的选择。顺便说一句,你的SQL客户机也是基于Java的吗?是的,据我所知,SQLDeveloper是基于Java的,但我不知道它是哪个驱动程序ses。你用的是什么jar?试试ojdbc5或ojdbc6。或者如果什么都不管用,那么你可能想试试OCI驱动程序。我想SQL Developer也用同样的驱动程序,因为他们为SQL Developer提供特定于平台的下载,OCI适合独立应用程序。是的,当然,在我看来,我的问题暗示了对Oracle长度语义的理解。只要“签入”和其他在搜索问题答案时发现此问题的人可能没有读过。不是七个字节-七个字符。é将是两个字节。剩余的6个字节是填充空格字符,每个字符占用一个字节。但是,鉴于dump函数只显示3个字节,这看起来确实是一个问题正如醋所建议的JDBC驱动程序。不知道如何获得ef bf bd。这是U+FFFD,未知或不可表示的字符的替换字符。我的数据库在UTF-8 charsetOk中,问题是驱动程序,ojdbc14.jar==>当使用此驱动程序时,我得到>é<而不是>é<当我使用ojdbc5.jar或ojdbc6.jar驱动程序时,它是获得与SQLDeveloper中相同的结果:>é<谢谢您的回答–zor