2011-09-05 7 views
5

Sto cercando il modo migliore per modificare un tipo di dati di una colonna in una tabella popolata. Oracle consente solo la modifica del tipo di dati nelle colonne con valori nulli.Modifica il tipo di dati della colonna nel database di produzione

La mia soluzione, finora, è un'istruzione PLSQL che memorizza i dati della colonna da modificare in una raccolta, altera la tabella e quindi scorre sulla raccolta, ripristinando i dati originali con il tipo di dati convertito.

-- Before: my_table (id NUMBER, my_value VARCHAR2(255)) 
-- After: my_table (id NUMBER, my_value NUMBER) 

DECLARE 
    TYPE record_type IS RECORD (id NUMBER, my_value VARCHAR2(255)); 
    TYPE nested_type IS TABLE OF record_type; 
    foo nested_type; 
BEGIN 
    SELECT id, my_value BULK COLLECT INTO foo FROM my_table; 
    UPDATE my_table SET my_value = NULL; 
    EXECUTE IMMEDIATE 'ALTER TABLE my_table MODIFY my_value NUMBER'; 
    FOR i IN foo.FIRST .. foo.LAST 
    LOOP 
    UPDATE my_table 
     SET = TO_NUMBER(foo(i).my_value) 
     WHERE my_table.id = foo(i).id; 
    END LOOP; 
END; 
/

Sto cercando un modo più esperto per farlo.

+2

La semplice risposta è interrompere il database in produzione per alcune ore mentre lo si fa correttamente. Non garantirai mai ** che hai tutto corretto a meno che tu non impedisca alle persone di scrivere sul DB. – Ben

+0

Quanto è grande il tavolo? Il tavolo deve essere disponibile per l'applicazione durante questo periodo? –

risposta

6

La soluzione è sbagliata. L'istruzione alter table esegue un commit implicito. Quindi la soluzione presenta i seguenti problemi:

  • Non è possibile eseguire il rollback dopo alterare l'ALTER TABLE e in caso di crash del database dopo l'istruzione ALTER TABLE si perderanno i dati
  • Tra la selezione e gli utenti degli aggiornamenti possono apportare modifiche ai dati

Invece dovresti dare un'occhiata alla ridefinizione online di Oracle.

+0

Grazie, Steve. Ho scoperto che avrò una finestra temporale per fare manutenzione, quindi userò l'approccio di @Rene. –

5

La tua soluzione sembra un po 'pericolosa per me. Caricare i valori in una raccolta e successivamente eliminarli dalla tabella significa che questi valori sono ora disponibili solo in memoria. Se qualcosa va storto sono persi.

La procedura corretta è:

  1. aggiungere una colonna del tipo corretto al tavolo.
  2. Copia i valori nella nuova colonna.
  3. Elimina la vecchia colonna.
  4. Rinomina la nuova colonna con il nome della vecchia colonna.
+0

Questo risolve il problema della perdita di dati anche se un altro utente apporta modifiche ai dati, come sottolineato da @steve? –

+0

No, non lo è. Ma ti lascerà tutti i tuoi dati intatti nei casi in cui puoi portare l'applicazione offline per la manutenzione. – Rene

+0

Apprezzo il tuo pensiero in questo, grazie. –

Problemi correlati