【发布时间】:2016-09-16 21:43:54
【问题描述】:
OJDBC 的工作之一是将 Oracle 数据类型映射到 Java 类型。
但是,我们注意到,如果我们提供 CHAR 数据类型,它不会映射到 java.lang.String。显示此行为的版本是:OJDBC7 v12.1.0.2 和 OJDBC6 v12.1.0.1。旧版本确实将CHAR 数据类型映射到:java.lang.String。
在深入挖掘时,我们发现在 OJDBC 的 oracle.jdbc.driver 包中存在一个类:StructMetaData,它实现了 Oracle 数据类型到 Java 类型的映射。其中有一个方法:'getColumnClassName(int arg0)' 值得关注。我们注意到,对于 OJDBC v7,映射到java.lang.String 的案例如下:
int arg1 = this.getColumnType(arg0);
switch (arg1) {
case -104:
return "oracle.sql.INTERVALDS";
case -103:
return "oracle.sql.INTERVALYM";
case -102:
return "oracle.sql.TIMESTAMPLTZ";
case -101:
return "oracle.sql.TIMESTAMPTZ";
case -15:
case -9:
case 12:
return "java.lang.String";
...
但是,在旧的 OJDBC 实现中,它看起来像这样:
int arg1 = this.getColumnType(arg0);
switch (arg1) {
case -104:
return "oracle.sql.INTERVALDS";
case -103:
return "oracle.sql.INTERVALYM";
case -102:
return "oracle.sql.TIMESTAMPLTZ";
case -101:
return "oracle.sql.TIMESTAMPTZ";
case -15:
case -9:
case 1:
case 12:
return "java.lang.String";
...
在后一种情况下,还有一个映射到java.lang.String 的情况,即。 '情况1'。在上面显示的第一个代码 sn-p 中,此“案例 1”未映射到 java.lang.String。
深入研究,这个“案例 1”被映射到同一 StructMetaData 类的 getColumnTypeName(int arg0 ) 方法中的 CHAR:
public String getColumnTypeName(int arg0) throws SQLException {
int arg1 = this.getColumnType(arg0);
int arg2 = this.getValidColumnIndex(arg0);
switch (arg1) {
case -104:
return "INTERVALDS";
case -103:
return "INTERVALYM";
case -102:
return "TIMESTAMP WITH LOCAL TIME ZONE";
case -101:
return "TIMESTAMP WITH TIME ZONE";
case -15:
return "NCHAR";
case -13:
return "BFILE";
case -9:
return "NVARCHAR";
case -2:
return "RAW";
case 1:
return "CHAR";
...
因此,如果我们使用 OJDBC 7 或 OJDBC6 v12.1.0.1 并指定 CHAR 作为列的数据类型,则以下代码在调用该列的索引时返回 null:
for (int i = 1; i <= resultSetMetaData.getColumnCount(); i++) {
...
resultSetMetaData.getColumnClassName(columnIndex)
...
如果我替换旧版本的 OJDBC jar(例如:11.2.0.3),则返回相同的代码:java.lang.String。这是一个错误还是被设计删除?
以前有人遇到过同样的问题吗?
【问题讨论】:
-
您查看过驱动程序的发行说明吗?如果您认为这是错误的,请通过 My Oracle Support 打开 SR。我对所提供的解决方案非常满意。