Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why would number columns' scale and/or precision differ in JDBC from Oracle 10 to 11?

Tags:

oracle

jdbc

For our database development we have on one hand a full schema DDL script, for scratch installs, and on the other a set of sequential "delta" scripts, for upgrades (each script is recorded as executed or not in a special database table).

To test this we have an ant target that install an older version, upgrades it and compares the schema to a newly created one. We use JDBC MetaData to compare the schemas and with Oracle 10 this worked just great.

Now we've upgraded to Oracle 11 and moved from ojdbc14.jar to ojdbc6.jar. The test still runs green on Oracle 10, but on Oracle 11 we get (two typical examples):

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>

Looks almost (-127 is not a nice scale now is it) OK, if we had done something wrong. But the very same files worked before and here are the script statements:

DDL script:

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

CREATE TABLE <table Y> ( 
...
<column B> NUMBER DEFAULT 1 NOT NULL,
...
) 

Delta script:

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)

And here is the JDBC MetaData code:

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");
}
}

Yes, the column index starts from 1 and it is the toString() value that is used to compare the different columns (also used in the error output above).

I've debugged this code and as far as I can see, the Oracle JDBC driver gets these values when internally "describing" the table to produce the MetaData.

Note that both schemas are in the very same database instance and the JDBC connections are both made by the very same JDBC library. The same discrepancies are produced when using the older ojdbc14.jar, but never in Oracle 10.

Does anybody have any input on how this can be? I'm stuck and we're left without a trustable test of our database upgrade scripts.

like image 935
Mirvnillith Avatar asked Jan 25 '10 16:01

Mirvnillith


1 Answers

I'd vote for it being a bug in the ojdbc driver. That said, I would probably call the DBMS_METADATA packages for extracting DDL. The ResultSetMetaData seems more focused on determining the types in a result set as opposed to determining the metadata of database objects themselves.

like image 159
Adam Hawkes Avatar answered Sep 27 '22 18:09

Adam Hawkes