2011-09-05 11 views
5

データが入っている表の列のデータ型を変更する最適な方法を探しています。 Oracleは、NULL値を持つ列のデータ型の変更のみを許可します。本番データベースの列データ型を変更する

私の解決策は、変更する列のデータをコレクションに格納し、テーブルを変更してコレクションを反復処理し、元のデータをデータ型に変換して復元するPLSQLステートメントです。

-- Before: my_table (id NUMBER, my_value VARCHAR2(255)) 
-- After: my_table (id NUMBER, my_value NUMBER) 

DECLARE 
    TYPE record_type IS RECORD (id NUMBER, my_value VARCHAR2(255)); 
    TYPE nested_type IS TABLE OF record_type; 
    foo nested_type; 
BEGIN 
    SELECT id, my_value BULK COLLECT INTO foo FROM my_table; 
    UPDATE my_table SET my_value = NULL; 
    EXECUTE IMMEDIATE 'ALTER TABLE my_table MODIFY my_value NUMBER'; 
    FOR i IN foo.FIRST .. foo.LAST 
    LOOP 
    UPDATE my_table 
     SET = TO_NUMBER(foo(i).my_value) 
     WHERE my_table.id = foo(i).id; 
    END LOOP; 
END; 
/

私はそれをもっと熟練した方法で探しています。

+2

これを正しく実行している間、データベースが数時間稼働中に停止するという単純な答えです。 **あなたがDBに書く人を止めない限り、あなたはすべてが正しいことを**保証することはありません。 – Ben

+0

テーブルの大きさはどれくらいですか?この時間にテーブルをアプリケーションで使用できるようにする必要がありますか? –

答えて

6

解決策は間違っています。 alter table文は、暗黙のコミットを行います。だから、解決策は次のような問題がある:

  • あなたは、ALTER TABLE文を変更し、あなたが選択すると、更新ユーザー間のデータ
  • を失うことになるALTER TABLE文の後にデータベースがクラッシュした場合の後にロールバックすることはできません変更を行うことができますデータへ

代わりに、Oracleのオンライン再定義を参照する必要があります。

+0

ありがとう、steve。私はメンテナンスのための時間枠を持っていることが分かります。@ Reneのアプローチを使用します。 –

5

あなたのソリューションは私にとっては危険です。コレクションに値を読み込んだ後にテーブルから削除すると、これらの値はメモリ内でのみ使用できるようになります。何かがうまくいかなければ、彼らは失われます。

適切な手順は次のとおりです。

  1. がテーブルに正しいタイプの列を追加します。
  2. 値を新しい列にコピーします。
  3. 古い列を削除します。
  4. 新しい列の名前を古い列の名前に変更します。
+0

これは、@ steveで指摘されているように、別のユーザーがデータを変更してもデータの損失の問題を解決しますか? –

+0

いいえ、そうではありません。しかし、メンテナンスのためにアプリケーションをオフラインにすることができる場合は、すべてのデータをそのまま残すことができます。 – Rene

+0

あなたの考えをありがとう、ありがとう。 –

関連する問題