Oracle
 sql >> Base de Dados >  >> RDS >> Oracle

CLOB vs. VARCHAR2 e existem outras alternativas?


É uma péssima ideia usar um tipo de dados CLOB para uma coluna que deveria ser VARCHAR2(1). Além das sobrecargas (que são realmente mínimas, pois o Oracle tratará CLOBs inline de <4000 caracteres como VARCHAR2), devemos sempre nos esforçar para usar a representação mais precisa de nossos dados no esquema:é apenas uma boa prática.

Isso realmente parece um problema com a ferramenta DevArt, ou talvez sua compreensão de como usá-la (sem ofensa). Deve haver alguma maneira de você especificar o tipo de dados do atributo de uma entidade e/ou uma maneira de mapear essas especificações para os tipos de dados físicos do Oracle. Peço desculpas se isso parece um pouco vago, não estou familiarizado com o produto.

Então, este é o 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 corrigi-lo usando DDL para alterar a estrutura da tabela. Como o esquema tem muitas dessas colunas, vale a pena automatizar o processo. Esta função elimina a coluna existente e a recria como um VARCHAR2. Oferece a opção de migrar dados da coluna CLOB para a coluna VARCHAR2; você provavelmente não precisa disso, mas está lá para ser completo. (Este não é um código de qualidade de produção - ele precisa de tratamento de erros, gerenciamento de restrições 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;
/

Então, vamos mudar essa coluna...
SQL> exec clob2vc ('T69', 'COL1', 1)

PL/SQL procedure successfully completed.

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

SQL>

Chamar esse procedimento pode ser automatizado ou com script das maneiras usuais.