Una volta che una tabella viene versionata, può nascere la necessità di modificarla aggiungendo delle nuovo colonne. Come si fa in questo caso a modificare una tabella versionata senza sversionarla?
Semplice utilizziamo i package messi a disposizione da OWM, peccato che in alcuni casi ed in particolare per la versione 11g possono essere soggetti ad alcuni bug.
CASO DI TEST: Abbiamo una tabella avente la seguente struttura, indicata di seguito, a cui dobbiamo aggiungere 3 colonne not null.
A questo punto aggiungiamo le 3 colonne utilizzando come dice la documentazione la procedura BEGINDDL/COMMITDDL eseguendo questi comandi:
BEGIN DBMS_WM.BEGINDDL('T4967.AGGRRULECUBE'); END;
alter table T4967.AGGRRULECUBE_LTS ADD("RULE_PARAMETER"
VARCHAR2(2000) NOT NULL);
alter table T4967.AGGRRULECUBE_LTS ADD("CONTEXTID"
VARCHAR2(60) NOT NULL);
alter table T4967.AGGRRULECUBE_LTS ADD("CUBESTATTYPE"
VARCHAR2(20) NOT NULL);
BEGIN DBMS_WM.COMMITDDL('T4967.AGGRRULECUBE'); END;
Facendo in questo modo, avremo subito il seguente errore nel momento in cui effettueremo la COMMITDDL:
...
BEGIN DBMS_WM.COMMITDDL('T4967.AGGRRULECUBE'); END;
Report error -
ORA-00904: "RULE_PARAMETER": identificativo non valido
ORA-06512: a "WMSYS.LT", line 12487
ORA-06512: a line 1
00904. 00000 - "%s: invalid identifier"
*Cause:
*Action:
Allora continuiamo riportando tutto a prima della BEGINDDL e proviamo un altro approccio non piĂą tutte le operazioni insieme ma invece le dividiamo:
BEGIN DBMS_WM.BEGINDDL('T4967.AGGRRULECUBE'); END;
alter table T4967.AGGRRULECUBE_LTS ADD("RULE_PARAMETER"
VARCHAR2(2000) NOT NULL);
BEGIN DBMS_WM.COMMITDDL('T4967.AGGRRULECUBE'); END;
Anche in questo caso niente da fare in fase di COMMIT avremo lo stesso errore indicato sopra. Allora procediamo ancora spacchettando il comando visto sopra nei seguenti:
BEGIN DBMS_WM.BEGINDDL('T4967.AGGRRULECUBE'); END;
alter table T4967.AGGRRULECUBE_LTS ADD("RULE_PARAMETER"
VARCHAR2(2000) );
BEGIN DBMS_WM.COMMITDDL('T4967.AGGRRULECUBE'); END;
BEGIN DBMS_WM.BEGINDDL('T4967.AGGRRULECUBE'); END;
alter table T4967.AGGRRULECUBE_LTS MODIFY("RULE_PARAMETER"
NOT NULL);
BEGIN DBMS_WM.COMMITDDL('T4967.AGGRRULECUBE'); END;
blocco anonimo completato
table T4967.AGGRRULECUBE_LTS modificato.
blocco anonimo completato
blocco anonimo completato
table T4967.AGGRRULECUBE_LTS modificato.
blocco anonimo completato
Questa volta sembrerebbe tutto ok, peccato che se guardiamo la describe della tabella il nuovo campo aggiunto non risulta essere NOT NULL ma ancora NULLABLE.
Come si spiega il tutto? Semplice abbiamo un piccolo BUG fissato nella 12c, come lo risolviamo?
Effettuiamo l'ultima operazione di BEGINDDL/COMMITDDL da una sessione differente e come magia anche se nella describe il campo apparirà sempre NULLABLE il sw però avrà creato un check constraint di NOT NULL sulla tabella.
BEGIN DBMS_WM.BEGINDDL('T4967.AGGRRULECUBE'); END;
alter table T4967.AGGRRULECUBE_LTS MODIFY("RULE_PARAMETER"
NOT NULL);
BEGIN DBMS_WM.COMMITDDL('T4967.AGGRRULECUBE'); END;
...
blocco anonimo completato
table T4967.AGGRRULECUBE_LTS modificato.
blocco anonimo completato
Occhio però ... se lo fate due volte di seguito verranno creati due check constraint che fanno la stessa cosa come in figura sopra.
Nessun commento:
Posta un commento