sql >> Base de Datos >  >> RDS >> Oracle

CLOB vs VARCHAR2 y hay otras alternativas?

Es una muy mala idea usar un tipo de datos CLOB para una columna que debería ser VARCHAR2(1). Además de los gastos generales (que en realidad son mínimos, ya que Oracle tratará los CLOB en línea de <4000 caracteres como VARCHAR2), siempre debemos esforzarnos por utilizar la representación más precisa de nuestros datos en el esquema:es solo una buena práctica.

Esto realmente parece un problema con la herramienta DevArt, o tal vez su comprensión de cómo usarla (sin ofender). Debería haber alguna forma de especificar el tipo de datos del atributo de una entidad y/o una forma de asignar esas especificaciones a los tipos de datos físicos de Oracle. Me disculpo si esto parece un poco vago, no estoy familiarizado con el producto.

Entonces, este es el problema básico:

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>

Podemos arreglarlo usando DDL para alterar la estructura de la tabla. Debido a que el esquema tiene muchas de estas columnas, vale la pena automatizar el proceso. Esta función elimina la columna existente y la vuelve a crear como VARCHAR2. Ofrece la opción de migrar datos de la columna CLOB a la columna VARCHAR2; probablemente no necesite esto, pero está ahí para completarlo. (Este no es código de calidad de producción; necesita manejo de errores, manejo de restricciones NOT NULL, etc.)

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;
/

Entonces, cambiemos esa columna...

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

PL/SQL procedure successfully completed.

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

SQL>

La llamada a este procedimiento se puede automatizar o programar de la forma habitual.