2009-06-22 16 views
32

Sto cercando di compilare un collega per eseguire alcuni lavori di Oracle e ho avuto un problema. Nel tentativo di scrivere uno script per modificare una colonna nullable, mi sono imbattuto in bella errore ORA-01451:MODIFY COLUMN in oracle - Come verificare se una colonna è annullabile prima di impostare su null?

ORA-01451: column to be modified to NULL cannot be modified to NULL 

Questo sta accadendo perché la colonna è già NULL. Abbiamo diversi database che devono essere ascoltati, quindi nella mia ipotesi errata ho pensato che impostarlo su NULL avrebbe dovuto funzionare su tutta la linea per assicurarmi che tutti fossero aggiornati, indipendentemente dal fatto che avessero impostato manualmente questa colonna su nullable o meno. Tuttavia, questo a quanto pare causa un errore per alcune persone che hanno già la colonna come nullable.

Come si verifica se una colonna è già annullabile in modo da evitare l'errore? Qualcosa che avrebbe realizzare questa idea:

IF(MyTable.MyColumn IS NOT NULLABLE) 
    ALTER TABLE MyTable MODIFY(MyColumn NULL); 

risposta

41

Si potrebbe fare questo in PL/SQL:

declare 
    l_nullable varchar2(1); 
begin 
    select nullable into l_nullable 
    from user_tab_columns 
    where table_name = 'MYTABLE' 
    and column_name = 'MYCOLUMN'; 

    if l_nullable = 'N' then 
    execute immediate 'alter table mytable modify (mycolumn null)'; 
    end if; 
end; 
+0

Grazie Tony! Ho ottenuto questo lavoro (con una piccola soluzione per chiudere la citazione sull'esecuzione immediata) e ora siamo in affari! –

+0

Suggerirei che l'interrogazione del dizionario dei dati ogni volta che si esegue questo ALTER TABLE sarebbe piuttosto inefficiente, rispetto alla semplice gestione dell'eccezione se si verifica. –

+0

Jeffrey, probabilmente sei corretto, ma questo era per uno script di modifica dello schema, quindi è una situazione una sola volta per database. Una volta che la modifica è stata apportata, non verrà eseguita di nuovo. –

19

solo fare il tavolo alter e intercettare l'eccezione.

DECLARE 
    allready_null EXCEPTION; 
    PRAGMA EXCEPTION_INIT(allready_null, -1451); 
BEGIN 
    execute immediate 'ALTER TABLE TAB MODIFY(COL NULL)'; 
EXCEPTION 
    WHEN allready_null THEN 
     null; -- handle the error 
END; 
/

se non si desidera utilizzare PL/SQL

set feedback off 
    set echo off 
    set feedback off 
    set pages 0 
    set head off 

    spool to_null.sql 

    select 'alter table TAB modify (COL NULL);' 
    from user_tab_columns 
    where table_name = 'TAB' 
    and column_name = 'COL' 
    and nullable = 'N'; 

    spool off 
    set feedback on 
    set echo on 
    set termout on 
    @@to_null.sql 
    host rm -f to_null.sql 

o semplicemente fare il tavolo alter e ignorare l'errore.

+0

+1 per l'approccio "catch exception if fallisce", che è più efficiente di interrogare il dizionario dati ogni volta –

+1

Voglio solo aggiungere che questo approccio è molto usato in PLSQL – Rene

+1

Aggiungi 'host rm -f to_null.sql' (* nix) o 'host del/f to_null.sql' per evitare di sporcare la directory con file temporanei. –

Problemi correlati