Oracle
 sql >> Datenbank >  >> RDS >> Oracle

CLOB vs. VARCHAR2 und gibt es andere Alternativen?

Es ist eine sehr schlechte Idee, einen CLOB-Datentyp für eine Spalte zu verwenden, die VARCHAR2(1) sein sollte. Abgesehen von den Overheads (die tatsächlich minimal sind, da Oracle Inline-CLOBs mit <4000 Zeichen als VARCHAR2 behandelt) sollten wir immer danach streben, die genaueste Darstellung unserer Daten im Schema zu verwenden:Es ist einfach eine gute Praxis.

Dies scheint wirklich ein Problem mit dem DevArt-Tool zu sein, oder vielleicht mit Ihrem Verständnis, wie man es benutzt (nichts für ungut). Es sollte eine Möglichkeit geben, den Datentyp des Attributs einer Entität anzugeben und/oder diese Spezifikationen den physischen Datentypen von Oracle zuzuordnen. Ich entschuldige mich, wenn dies etwas vage erscheint, ich bin mit dem Produkt nicht vertraut.

Das ist also das Grundproblem:

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>

Wir können es beheben, indem wir DDL verwenden, um die Tabellenstruktur zu ändern. Da das Schema viele solcher Spalten hat, lohnt es sich, den Prozess zu automatisieren. Diese Funktion löscht die vorhandene Spalte und erstellt sie als VARCHAR2 neu. Es bietet die Option, Daten in der CLOB-Spalte in die VARCHAR2-Spalte zu migrieren; Sie brauchen das wahrscheinlich nicht, aber es dient der Vollständigkeit. (Dies ist kein Qualitätscode für die Produktion – er erfordert Fehlerbehandlung, Verwaltung von NOT NULL-Einschränkungen usw.)

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

Also ändern wir diese Spalte...

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

PL/SQL procedure successfully completed.

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

SQL>

Der Aufruf dieser Prozedur kann auf die übliche Weise automatisiert oder per Skript ausgeführt werden.