对于我们的数据库开发,我们一方面有一个完整的模式DDL脚本,用于临时安装,另一方面是一组顺序的"delta"脚本,用于升级(每个脚本记录为执行或不在特殊的数据库表中).
为了测试这个,我们有一个安装旧版本的ant目标,升级它并将模式与新创建的模型进行比较.我们使用JDBC MetaData来比较模式,并且使用Oracle 10,这非常有用.
现在我们已升级到Oracle 11并从ojdbc14.jar迁移到ojdbc6.jar.测试在Oracle 10上仍然运行绿色,但在Oracle 11上我们得到(两个典型示例):
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>
Run Code Online (Sandbox Code Playgroud)
看起来差不多(-127现在不是很好的规模)好吧,如果我们做错了什么.但是之前的文件非常相同,这里是脚本语句:
DDL脚本:
CREATE TABLE <table X> (
...
<column B> NUMBER(1) DEFAULT 0 NOT NULL,
...
)
CREATE TABLE <table Y> (
...
<column B> NUMBER DEFAULT 1 NOT NULL,
...
)
Run Code Online (Sandbox Code Playgroud)
Delta脚本:
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)
Run Code Online (Sandbox Code Playgroud)
这是JDBC MetaData代码:
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");
}
}
Run Code Online (Sandbox Code Playgroud)
是的,列索引从1开始,它是用于比较不同列的toString()值(也用于上面的错误输出).
我调试了这段代码,据我所知,Oracle JDBC驱动程序在内部"描述"表以生成MetaData时获取这些值.
请注意,两个模式都在同一个数据库实例中,JDBC连接都是由完全相同的JDBC库创建的.使用较旧的ojdbc14.jar时会产生相同的差异,但在Oracle 10中则不会产生相同的差异.
有没有人对这是怎么回事?我被困住了,我们没有对我们的数据库升级脚本进行可靠的测试.
我投票支持它是 ojdbc 驱动程序中的一个错误。也就是说,我可能会调用DBMS_METADATA用于提取 DDL 的包。似乎ResultSetMetaData更侧重于确定结果集中的类型,而不是确定数据库对象本身的元数据。
| 归档时间: |
|
| 查看次数: |
2230 次 |
| 最近记录: |