2010-01-25 5 views
7

Für unsere Datenbankentwicklung haben wir auf der einen Seite ein vollständiges Schema-DDL-Skript für Scratch-Installationen und auf der anderen Seite eine Reihe von sequenziellen "Delta" -Skripten für Upgrades (jedes Skript wird als ausgeführt oder nicht in einer speziellen Datenbanktabelle aufgezeichnet)).Warum unterscheiden sich Skalierung und/oder Genauigkeit von Zahlenspalten in JDBC von Oracle 10 bis 11?

Um dies zu testen, haben wir ein ant-Ziel, das eine ältere Version installiert, aktualisiert und das Schema mit einem neu erstellten vergleicht. Wir verwenden JDBC MetaData, um die Schemas zu vergleichen, und mit Oracle 10 funktionierte das großartig.

Jetzt haben wir auf Oracle 11 aktualisiert und von ojdbc14.jar zu ojdbc6.jar gewechselt. Der Test läuft noch grün auf 10 Oracle, aber auf Oracle 11 erhalten wir (zwei typische Beispiele):

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> 

fast Sieht aus (-127 ist keine schöne Skala jetzt ist es) OK, wenn wir etwas getan hatte, falsch . Aber die gleichen Dateien gearbeitet und hier sind die Skript-Anweisungen:

DDL Skript:

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

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

Delta Skript:

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) 

Und hier ist der JDBC MetaDaten 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"); 
} 
} 

Ja, der Spaltenindex beginnt bei 1, und es ist der Wert toString(), der zum Vergleich von t verwendet wird Die verschiedenen Spalten (auch in der Fehlerausgabe oben verwendet).

Ich habe diesen Code debugged und soweit ich sehen kann, erhält der Oracle JDBC-Treiber diese Werte, wenn er intern die Tabelle "beschreibt", um die MetaData zu erzeugen.

Beachten Sie, dass sich beide Schemas in derselben Datenbankinstanz befinden und dass die JDBC-Verbindungen von derselben JDBC-Bibliothek erstellt werden. Die gleichen Diskrepanzen werden bei der Verwendung der älteren Datei "ojdbc14.jar", aber niemals bei "Oracle 10" verursacht.

Hat jemand eine Eingabe dazu, wie das sein kann? Ich stehe fest und wir haben keinen vertrauenswürdigen Test unserer Datenbank-Upgrade-Skripte.

+0

Es sieht so aus, dass getScale() einen negativen Wert für Spalten zurückgibt, die nur als NUMBER statt als NUMBER (x) oder NUMBER (x, y) definiert sind. Es gibt einige Diskussionen, die Sie auf Google finden können, die sich mit dem gleichen Problem befassen, zB: http://www.experts-exchange.com/Programming/Languages/Java/Q_21360469.html Nicht sicher, warum es anders funktioniert Orakel 10 und 11 obwohl. Könnte ein Fehler im JDBC-Treiber auftreten? Es könnte eine gute Idee sein, die Genauigkeit und Skalierung explizit für Datentypen in Ihren DDL-Anweisungen btw anzugeben. – maximdim

+1

Sehen Sie, was Tom dazu zu sagen hat. http://asktom.oracle.com/ –

+1

+1 für die Frage Tom - er hat immer die Antwort, wahrscheinlich bevor Sie sogar die Frage stellen :-) – jckdnk111

Antwort

1

Ich würde dafür stimmen, dass es sich um einen Fehler im ojdbc-Treiber handelt. Das heißt, ich würde wahrscheinlich die DBMS_METADATA Pakete zum Extrahieren von DDL aufrufen. Die ResultSetMetaData scheint sich mehr auf die Ermittlung der Typen in einer Ergebnismenge zu konzentrieren als auf die Metadaten der Datenbankobjekte selbst.

+0

Ich werde dies als die Antwort akzeptieren, wie ich am Ende mit ALL_TAB_COLUMNS statt. .. – Mirvnillith

Verwandte Themen