为什么要对列进行编号';从Oracle10到Oracle11,JDBC的规模和/或精度不同?

为什么要对列进行编号';从Oracle10到Oracle11,JDBC的规模和/或精度不同?,oracle,jdbc,Oracle,Jdbc,对于我们的数据库开发,我们一方面有一个完整的模式DDL脚本,用于临时安装,另一方面有一组连续的“增量”脚本,用于升级(每个脚本都记录在一个特殊的数据库表中是否执行) 为了测试这一点,我们有一个ant目标,它安装一个旧版本,升级它,并将模式与新创建的模式进行比较。我们使用JDBC元数据来比较模式,与Oracle 10相比,这非常有效 现在我们已经升级到Oracle 11,并从ojdbc14.jar迁移到ojdbc6.jar。测试在Oracle 10上仍然以绿色运行,但在Oracle 11上我们得到

对于我们的数据库开发,我们一方面有一个完整的模式DDL脚本,用于临时安装,另一方面有一组连续的“增量”脚本,用于升级(每个脚本都记录在一个特殊的数据库表中是否执行)

为了测试这一点,我们有一个ant目标,它安装一个旧版本,升级它,并将模式与新创建的模式进行比较。我们使用JDBC元数据来比较模式,与Oracle 10相比,这非常有效

现在我们已经升级到Oracle 11,并从ojdbc14.jar迁移到ojdbc6.jar。测试在Oracle 10上仍然以绿色运行,但在Oracle 11上我们得到了(两个典型示例):

是的,列索引从1开始,它是用于比较不同列的toString()值(也用于上面的错误输出)

我已经调试了这段代码,据我所知,Oracle JDBC驱动程序在内部“描述”表以生成元数据时会获取这些值

请注意,这两个模式都位于同一个数据库实例中,JDBC连接都由同一个JDBC库进行。使用较旧的ojdbc14.jar时也会产生相同的差异,但在Oracle 10中从未出现过这种差异


有人对这一点有什么看法吗?我被卡住了,我们没有对数据库升级脚本进行可靠的测试。

我认为这是ojdbc驱动程序中的一个错误。也就是说,我可能会调用
DBMS\u元数据
包来提取DDL。
ResultSetMetaData
似乎更关注于确定结果集中的类型,而不是确定数据库对象本身的元数据。

看来getScale()只为定义为数字而不是数字(x)或数字(x,y)的列返回负值。你可以在谷歌上找到一些关于同样问题的讨论,例如:不确定为什么oracle 10和oracle 11的工作方式不同。可能是JDBC驱动程序中的错误?在DDL语句中总是显式地指定数据类型的精度和比例可能是个好主意。顺便说一句,看看Tom对此有何评论+问汤姆——他总是有答案,可能在你问这个问题之前:——)
Table <table X> has column <column A> as NUMBER(1,0) NOT NULL in <new schema>, but as NUMBER(0,0) NOT NULL in <upgraded schema>
Table <table Y> has column <column B> as NUMBER(0,-127) NOT NULL in <new schema>, but as NUMBER(0,0) NOT NULL in <upgraded schema>
CREATE TABLE <table X> ( 
...
<column B> NUMBER(1) DEFAULT 0 NOT NULL,
...
) 

CREATE TABLE <table Y> ( 
...
<column B> NUMBER DEFAULT 1 NOT NULL,
...
) 
ALTER TABLE <table X> ADD (
<column A> NUMBER(1) DEFAULT 0 NOT NULL
)

ALTER TABLE <table Y> ADD (<column B> NUMBER DEFAULT 1 NOT NULL)
public class Column {

String name;

int scale;

int precision;

boolean nullable;

String type;

public Column(ResultSetMetaData metaData, int column) throws SQLException {
    name = metaData.getColumnName(column);
    type = metaData.getColumnTypeName(column);
    scale = metaData.getScale(column);
    precision = metaData.getPrecision(column);
    nullable = metaData.isNullable(column) == ResultSetMetaData.columnNullable;
}

@Override
public String toString() {
    return type + "(" + precision + "," + scale + ") "
            + (nullable ? "NULL" : "NOT NULL");
}
}