Oracle
 sql >> Database >  >> RDS >> Oracle

CLOB vs VARCHAR2 e ci sono altre alternative?

È una pessima idea usare un tipo di dati CLOB per una colonna che dovrebbe essere VARCHAR2(1). A parte le spese generali (che in realtà sono minime, poiché Oracle tratterà i CLOB inline di <4000 caratteri come VARCHAR2) dovremmo sempre cercare di utilizzare la rappresentazione più accurata dei nostri dati nello schema:è solo una buona pratica.

Questo sembra davvero un problema con lo strumento DevArt, o forse la tua comprensione di come usarlo (senza offesa). Ci dovrebbe essere un modo per specificare il tipo di dati dell'attributo di un'entità e/o un modo per mappare tali specifiche ai tipi di dati fisici di Oracle. Mi scuso se questo sembra un po' vago, non conosco il prodotto.

Quindi, questo è il problema di base:

SQL> desc t69
 Name                                      Null?    Type
 ----------------------------------------- -------- --------
 COL1                                               CLOB

SQL>
SQL> alter table t69 modify col1 varchar2(1)
  2  /
alter table t69 modify col1 varchar2(1)
                       *
ERROR at line 1:
ORA-22859: invalid modification of columns


SQL>

Possiamo risolverlo usando DDL per alterare la struttura della tabella. Poiché lo schema ha molte di queste colonne, vale la pena automatizzare il processo. Questa funzione elimina la colonna esistente e la ricrea come VARCHAR2. Offre la possibilità di migrare i dati dalla colonna CLOB alla colonna VARCHAR2; probabilmente non hai bisogno di questo, ma è lì per completezza. (Questo non è un codice di qualità della produzione:richiede la gestione degli errori, la gestione dei vincoli NOT NULL, ecc.)

create or replace procedure clob2vc
  ( ptab in user_tables.table_name%type 
    , pcol in user_tab_columns.column_name%type
    , pcol_size in number
    , migrate_data in boolean := true )
is
begin
    if migrate_data
    then
        execute immediate 'alter table '||ptab
                    ||' add tmp_col varchar2('|| pcol_size|| ')';
        execute immediate             
                    'update '||ptab
                    ||' set tmp_col = substr('||pcol||',1,'||pcol_size||')';
    end if;
    execute immediate 'alter table '||ptab
                ||' drop column '|| pcol;

    if migrate_data
    then
        execute immediate 'alter table '||ptab
                    ||' rename column tmp_col to '|| pcol;
    else
        execute immediate 'alter table '||ptab
                    ||' add '||pcol||' varchar2('|| pcol_size|| ')';
    end if;
end;
/

Quindi, cambiamo quella colonna...

SQL> exec clob2vc ('T69', 'COL1', 1)

PL/SQL procedure successfully completed.

SQL> desc t69
 Name                                      Null?    Type
 ----------------------------------------- -------- ---------------
 COL1                                               VARCHAR2(1)

SQL>

La chiamata a questa procedura può essere automatizzata o eseguita tramite script nei soliti modi.