2015-09-29 9 views
6

Wir haben eine seltsame Situation in einer Tabelle in einer Oracle-Datenbank, wo das Löschen einer Spalte die Standardwerte einer anderen Spalte ändert. Hier ist das Szenario.Warum ändert diese Oracle DROP COLUMN den Standardwert einer anderen Spalte?

Ich habe meine Tabelle mit einigen Beispieldaten in ihm:

select * from SAMPLE_TABLE ; 

ID          BUSINESS_KEY 
---------------------------------------- --------------- 
e59bf31c-49a4-4638-bf6e-7d1be60f4dbb     1 
c0dabf78-d9ca-4072-832e-aeb618c7ed14     2 

I Spalte TYPE1 mit einer Check-Einschränkung hinzufügen (TYPE1_VAL1 oder TYPE1_VAL2) und einem Standardwert TYPE1_VAL2:

alter table SAMPLE_TABLE add TYPE1 varchar(10) default 'TYPE1_VAL2' not null check(TYPE1 in ('TYPE1_VAL1', 'TYPE1_VAL2')); 

Table altered. 

Ich sehe, dass der Standardwert (TYPE1_VAL2) ist korrekt ausgefüllt:

select * from SAMPLE_TABLE ; 

ID          BUSINESS_KEY TYPE1 
---------------------------------------- --------------- ---------- 
e59bf31c-49a4-4638-bf6e-7d1be60f4dbb     1 TYPE1_VAL2 
c0dabf78-d9ca-4072-832e-aeb618c7ed14     2 TYPE1_VAL2 

füge ich eine weitere Spalte TYPE2 mit einer anderen Kontrollbedingung (TYPE2_VAL1 oder TYPE2_VAL2) und einem Standardwert TYPE2_VAL2:

alter table SAMPLE_TABLE add TYPE2 varchar(15) default 'TYPE2_VAL2' not null check(TYPE2 in ('TYPE2_VAL1', 'TYPE2_VAL2')); 

Table altered. 

Und wieder Beachten Sie, dass der Standardwert (TYPE2_VAL2) korrekt ist:

SYSTEM(SYSTEM) @ DB_USER > select * from SAMPLE_TABLE ; 

ID          BUSINESS_KEY TYPE1  TYPE2 
---------------------------------------- --------------- ---------- --------------- 
e59bf31c-49a4-4638-bf6e-7d1be60f4dbb     1 TYPE1_VAL2 TYPE2_VAL2 
c0dabf78-d9ca-4072-832e-aeb618c7ed14     2 TYPE1_VAL2 TYPE2_VAL2 

Und jetzt für den komischen Teil. Als ich die erste Säule fallen, scheint es den Standardwert aus der gelöschten Spalte auf die verbleibenden Spalte anzuwenden:

ALTER TABLE SAMPLE_TABLE DROP COLUMN TYPE1; 

Table altered. 

select * from SAMPLE_TABLE ; 

ID          BUSINESS_KEY TYPE2 
---------------------------------------- --------------- --------------- 
e59bf31c-49a4-4638-bf6e-7d1be60f4dbb     1 TYPE1_VAL2 
c0dabf78-d9ca-4072-832e-aeb618c7ed14     2 TYPE1_VAL2 

Also, wo vor der TYPE2 Spalte TYPE2_VAL2 enthalten sind, ganz plötzlich nach dem Fall Es enthält TYPE1_VAL2. Es ist, als ob die Check-Einschränkung der gelöschten Spalte in diese Spalte verschoben würde.

Dies geschieht in unserer Testumgebung, in der Oracle Database 11g Version 11.2.0.4.0 - 64-Bit-Produktion unter Linux ausgeführt wird.

Auf unserer lokalen CentOS/Oracle XE Edition haben wir dieses Problem nicht.

Jede Idee, was dies verursachen könnte und wie wir dies verhindern können. Ist das per Design/ein Fehler/ein Fehler unsererseits?

+5

Riecht wie Sie eine SR öffnen müssen. –

+1

Das funktioniert bei mir unter 11.2.0.4 unter Solaris. Sieht wie ein sehr spezifischer Fehler aus. Wie Luc M sagte, müssen Sie wahrscheinlich eine SR öffnen. (Auch ich bin nicht sicher, warum jemand gestimmt, diese Frage zu schließen - das ist eine absolut gültige Frage für diese Seite ist.) –

+2

Es ist wahrscheinlich etwas mit der Tatsache zu tun, dass die Standardwerte nun als Metadaten gespeichert werden (obwohl das nicht ausdrücklich erwähnt in [die Dokumentation] (http://download.oracle.com/docs/cd/B28359_01/server.111/b28310/tables006.htm#sthref1856), ich denke, es wird angedeutet), wenn Sie den Standardwert mit einem nicht erstellen null Einschränkung. Meine Vermutung ist, dass es einen Fehler in Ihrer Version gibt, der die Metadaten durcheinander bringt, wenn die Spalte gelöscht wird, während Ihre zweite Spalte auf die Metadaten für den Standardwert für die erste Spalte verweist. – Boneist

Antwort

4

Dies ist ein Oracle-Fehler.

Es wird ausgelöst, indem eine Spalte mit einer NOT NULL Einschränkung und einem DEFAULT Wert zu einer vorhandenen Tabelle hinzugefügt wird.

Um die Spalte schnell hinzuzufügen, speichert Oracle 11g den Standardwert im Datenwörterbuch. Oracle nennt dies "Spaltenoptimierung hinzufügen".

Dies ist schneller, als den Standardwert in jede Tabellenzeile zu schreiben. Die Abfrage-Engine soll dann jeden NULL in der Tabellenzeile durch den Standardwert aus dem Datenwörterbuch ersetzen. Leider gibt es einige Bugs, die damit zusammenhängen.Sie erscheint eine Instanz zu sein:

17325413 Tropfen Spalte mit DEFAULT-Wert und NOT NULL Definition endet up mit gelöschte Spalte Datenscheibe zu Korruption führen schlagen

Sie können überprüfen, welche Spalten hinzugefügt wurden wie folgt aus:

select owner, object_name, name 
from dba_objects, col$ 
where bitand(col$.PROPERTY,1073741824)=1073741824 
and object_id=obj#; 

In unserem Fall wurden wir von einem anderen Fehler gestochen, die die falsche Ergebnisse für eine SELECT FOR UPDATE zurückgegeben.

Wir setzen Parameter _add_col_optim_enabled=FALSE diese „Optimierung“ auszuschalten. Alternativ können Sie möglicherweise auf eine spätere Oracle-Version aktualisieren, in der diese Fehler behoben sind.

Upgrade oder die obige Parametereinstellung wird Ihre vorhandene Tabelle nicht beheben, das beschädigt ist. Sie müssen diese Tabelle neu erstellen.