3

DB内の列に2つの列名で一時的にアクセスできるようにしたい。

なんで?列名の選択が間違っていたので、リファクタリングしたいと思います。列名を変更している間、Webアプリを安定させておきたいので、次のようにするとよいでしょう。

  1. 列bad_column_nameを指すbetter_column_nameという名前の(それを呼びましょう)シンボリックリンクがあります
  2. better_column_nameを使用するようにWebアプリケーションを変更します
  3. シンボリックリンクを削除し、列の名前をbetter_column_nameに変更します

「データベースのリファクタリング」では、これを実現するために、コミット時に同期される2番目の列を実際に追加することを提案しています。私は、Oracleを使用して、作業とオーバーヘッドを減らした、より簡単な方法があることを望んでいます。

4

5 に答える 5

4

両方の列名を使用するコードがある限り、そのテーブルに2つの(実際の)列があるという事実を回避する方法はわかりません。

正しい名前で新しい列を追加してから、どの列が変更されたかを確認し、それに応じて「その他」の列を更新するトリガーを作成します。したがって、更新されているものが何であれ、値は他の列と同期されます。

古い列を使用するすべてのコードが移行されたら、トリガーを削除して古い列を削除します。

編集

トリガーは次のようになります。

CREATE OR REPLACE TRIGGER ...
    ...
    UPDATE OF bad_column_name, better_column_name ON the_table 
    ...
BEGIN
  IF UPDATING ('BAD_COLUMN_NAME') THEN 
     :new.better_column_name = :new.bad_column_name
  END IF;

  IF UPDATING ('BETTER_COLUMN_NAME') THEN 
     :new.bad_column_name = :new.better_column_name
  END IF;
END;

ステートメントの順序は、IF誰かが両方の列を同時に更新した場合に、どちらの変更が「優先度が高い」かを制御します。

于 2011-04-28T10:32:36.357 に答える
3

テーブルの名前を変更します。

alter table mytable rename to mytable_old;

同じ列(およびもちろん他のすべての列)を指すbad_column_nameとbetter_column_nameの両方を含む元のテーブル名でビューを作成します。

create or replace view mytable as
  select column1
  , column2
  , ...
  , bad_column_name
  , bad_column_name better_column_name
  from mytable_old
;

このビューはデフォルトで更新可能であるため(ここではmytableに主キーがあると想定しています)、ビューから挿入/更新/削除できます。bad_column_nameまたはbetter_column_nameのどちらを使用してもかまいません。

リファクタリング後、ビューを削除し、テーブルと列の名前を変更します。

drop view mytable;
alter table mytable_old rename column bad_column_name to better_column_name;
alter table mytable_old rename to mytable;
于 2011-04-28T11:26:09.210 に答える
3

これに対する最善の解決策は、Oracle 11gリリース2:エディションベースの再定義でのみ利用できます。この非常に優れた機能により、特別なトリガーとビューを使用して、さまざまなバージョンのデータベース表とPL/SQLコードを維持できます。 詳細をご覧ください

基本的に、これは@AHorseWithNoNameの提案のOracleの組み込み実装で​​す。

于 2011-04-28T13:00:14.343 に答える
0

テーブルのビューを作成できます。そして、テーブルの代わりにそのビューを使用するようにアプリケーションを移植します。

create table t (bad_name varchar2(10), c2 varchar2(10));
create view vt as select bad_name AS good_name, c2 from t;

insert into vt (good_name, c2) values ('blub', 'blob');

select * from t;
select * from vt;
于 2011-04-28T10:55:59.543 に答える
-1

11gを使用している場合は、仮想列の使用を検討できます。順序を少し変更したくなるかもしれません。実際の列の名前を変更し、古い(悪い)名前を使用して仮想列を作成します。これは、後で削除できます。もちろん、制限される可能性があります。また、他のオブジェクトが無効になると、この順序が適切でなくなる可能性があります。

于 2011-04-28T10:06:40.780 に答える