Dla naszego rozwoju bazy danych mamy z jednej strony pełny schemat DDL skryptu, dla instalacji scratch, az drugiej zestaw sekwencyjnych skryptów "delta", dla aktualizacji (każdy skrypt jest rejestrowany jako wykonany lub nie w specjalnej tabeli bazy danych).Dlaczego liczba kolumn i/lub precyzja kolumn różni się w JDBC od Oracle 10 do 11?
Aby to przetestować, mamy ant target, który instaluje starszą wersję, aktualizuje ją i porównuje schemat z nowo utworzonym. Używamy JDBC MetaData do porównywania schematów iz Oracle 10 działało to świetnie.
Teraz dokonaliśmy aktualizacji do wersji Oracle 11 i przeniesieni z ojdbc14.jar do ojdbc6.jar. Test nadal działa na Oracle 10 zielony, ale na Oracle 11 otrzymujemy (dwa typowe przykłady):
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>
Wygląda prawie (-127 nie jest miły skala teraz jest to) OK, jeśli zrobiliśmy coś złego . Ale te same pliki pracował przed i oto wypowiedzi skryptu: Skrypt
DDL:
CREATE TABLE <table X> (
...
<column B> NUMBER(1) DEFAULT 0 NOT NULL,
...
)
CREATE TABLE <table Y> (
...
<column B> NUMBER DEFAULT 1 NOT NULL,
...
)
Delta skrypt:
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)
A oto kod JDBC Metadane:
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");
}
}
Tak, indeks kolumny zaczyna się od 1 i jest to wartość toString(), która jest używana do porównywania on różne kolumny (używane również w powyższym wyjściu błędu).
I debugowałem ten kod i o ile widzę, sterownik Oracle JDBC pobiera te wartości, gdy wewnętrznie "opisuje" tabelę w celu utworzenia MetaData.
Należy zauważyć, że oba schematy znajdują się w tej samej instancji bazy danych, a połączenia JDBC są tworzone przez tę samą bibliotekę JDBC. Te same różnice są produkowane przy użyciu starszej ojdbc14.jar, ale nigdy w Oracle 10.
Czy ktoś ma żadnych danych o tym, jak to może być? Utknąłem i zostaliśmy bez zaufanego testu naszych skryptów aktualizacji bazy danych.
Wygląda na to, że getScale() zwraca wartość ujemną dla kolumn zdefiniowanych jako tylko NUMBER zamiast NUMBER (x) lub NUMBER (x, y). W Google można znaleźć dyskusje dotyczące tego samego problemu, na przykład: http://www.experts-exchange.com/Programming/Languages/Java/Q_21360469.html Nie wiem, dlaczego działa inaczej wyrocznia 10 i 11 chociaż. Czy może to być błąd w sterowniku JDBC? Dobrym pomysłem jest wyraźne określenie precyzji i skali dla typów danych w instrukcjach DDL btw. – maximdim
Zobacz, co Tom ma do powiedzenia na ten temat. http://asktom.oracle.com/ –
+1 za pytanie Toma - zawsze ma odpowiedź, prawdopodobnie zanim jeszcze zadasz pytanie :-) – jckdnk111