sql >> データベース >  >> RDS >> Oracle

CLOBとVARCHAR2、および他の選択肢はありますか?

    VARCHAR2(1)であるはずの列にCLOBデータ型を使用することは非常に悪い考えです。オーバーヘッド(Oracleは4000文字未満のインラインCLOBをVARCHAR2として扱うため、実際には最小限です)は別として、スキーマ内のデータの最も正確な表現を使用するように常に努力する必要があります。これは良い習慣です。

    これは本当にDevArtツールの問題のように思えます。あるいは、おそらくそれを使用する方法の理解(違反なし)のようです。エンティティの属性のデータ型を指定する方法や、それらの仕様をOracleの物理データ型にマッピングする方法があるはずです。これが少し曖昧に思われる場合はお詫び申し上げます。私はこの製品に慣れていません。

    つまり、これが基本的な問題です。

    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>
    

    DDLを使用してテーブル構造を変更することで修正できます。スキーマにはそのような列がたくさんあるので、プロセスを自動化する価値があります。この関数は、既存の列を削除し、それをVARCHAR2として再作成します。 CLOB列のデータをVARCHAR2列に移行するオプションを提供します。おそらくこれは必要ありませんが、完全を期すためにあります。 (これは本番品質のコードではありません。エラー処理、NOT NULL制約の管理などが必要です)

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

    それでは、その列を変更しましょう...

    SQL> exec clob2vc ('T69', 'COL1', 1)
    
    PL/SQL procedure successfully completed.
    
    SQL> desc t69
     Name                                      Null?    Type
     ----------------------------------------- -------- ---------------
     COL1                                               VARCHAR2(1)
    
    SQL>
    

    このプロシージャの呼び出しは、通常の方法で自動化またはスクリプト化できます。



    1. postgresで最後に挿入されたシリアルIDを選択/表示します

    2. MySQLiプリペアドステートメントを使用すると、行数を取得してフェッチできません

    3. 2つのWebサイトで同じログイン

    4. 関数の取得DDLコマンド