2015-09-29 17 views
6

Abbiamo una situazione strana su una tabella in un database Oracle in cui il rilascio di una colonna comporta la modifica dei valori predefiniti di un'altra colonna. Ecco lo scenario.Perché questo DROP COLUMN Oracle altera il valore predefinito di un'altra colonna?

Io ho la mia tabella con alcuni dati di esempio in esso:

select * from SAMPLE_TABLE ; 

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

aggiungo colonna TIPO1 con un vincolo di controllo (TYPE1_VAL1 o TYPE1_VAL2) e un valore predefinito TYPE1_VAL2:

Vedo che il valore predefinito (TYPE1_VAL2) sia correttamente compilato in:

select * from SAMPLE_TABLE ; 

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

aggiunge un'altra colonna TIPO2 con un altro vincolo di controllo (TYPE2_VAL1 o TYPE2_VAL2) e un valore predefinito TYPE2_VAL2:

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

Table altered. 

E ancora verificare che il valore predefinito (TYPE2_VAL2) sia corretto:

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 

E ora per la parte strana. Quando ho cadere la prima colonna, sembra applicare il valore predefinito dalla colonna caduto sulla colonna rimanente:

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 

Allora, dove prima della colonna TIPO2 conteneva TYPE2_VAL2, tutto ad un tratto, dopo la caduta contiene TYPE1_VAL2. È come se il vincolo di controllo della colonna rilasciata si spostasse su questa colonna.

Questo accade nel nostro ambiente di test in cui è in esecuzione Oracle Database 11g Release 11.2.0.4.0 - Produzione a 64 bit su Linux.

Sulla nostra edizione CentOS/Oracle XE locale non abbiamo questo problema.

Qualche idea su cosa potrebbe causare questo e come possiamo evitare che ciò accada. È questo di progettazione/un bug/un errore da parte nostra?

+5

Odori di cui hai bisogno per aprire una SR. –

+1

Questo funziona per me su 11.2.0.4 su Solaris. Sembra un bug molto specifico. Come ha detto Luc M, probabilmente avrai bisogno di aprire un SR. (Inoltre, non sono sicuro del motivo per cui qualcuno ha votato per chiudere questa domanda - questa è una domanda perfettamente valida per questo sito.) –

+2

Probabilmente è qualcosa a che fare con il fatto che i valori di default sono ora memorizzati come metadati (sebbene ciò non sia esplicitamente dichiarato in [la documentazione] (http://download.oracle.com/docs/cd/B28359_01/server.111/b28310/tables006.htm#sthref1856), penso che sia implicito) se si crea il valore predefinito con un vincolo nullo. La mia ipotesi è che nella tua versione ci sia un bug che rovina i metadati quando la colonna viene rilasciata, lasciando la seconda colonna puntata sui metadati del valore predefinito per la prima colonna. – Boneist

risposta

4

Questo è un bug Oracle.

Viene attivato aggiungendo una colonna con un vincolo NOT NULL e un valore DEFAULT a una tabella esistente.

Per aggiungere rapidamente la colonna, Oracle 11g memorizza il valore predefinito nel dizionario dati. Oracle chiama questo "aggiungi ottimizzazione colonna".

Questo è più veloce della scrittura del valore predefinito in ogni riga della tabella. Si suppone quindi che il motore di query sostituisca qualsiasi NULL nella riga della tabella con il valore predefinito dal dizionario dei dati. Sfortunatamente ci sono diversi bug relativi a questo.Il vostro sembra essere un caso di:

17325413 colonna di goccia con il valore di impostazione predefinita e non definizione NULL finisce con i dati della colonna caduto colpendo disco che porta alla corruzione

È possibile verificare quali sono state aggiunte le colonne in questo modo:

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

Nel nostro caso, ci sono stati punti da un bug diversa che ha restituito i risultati non corretti per una SELECT FOR UPDATE.

Impostiamo il parametro _add_col_optim_enabled=FALSE per disattivare questa "ottimizzazione". In alternativa, potresti essere in grado di eseguire l'aggiornamento a una versione Oracle successiva in cui questi bug sono stati risolti.

L'aggiornamento o l'impostazione del parametro precedente non risolverà la tabella esistente, che è corrotta. È necessario ricreare quella tabella.

Problemi correlati