Java 为什么JDBC驱动程序会在Oracle数据库的查询字段之外填充一些空白字符?
下面是在Oracle 10g/UTF-8数据库中创建表的代码: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('é
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