非一時的なテーブルを一時的なテーブルにアップグレードすると、一時的なテーブルの非一時的なビューを作成する古いアプリケーションとの互換性を実現できます。ビューは、一時的なデータを現在有効なデータに縮小します。このようなビューの場合、一時テーブルに対して正しいアクションを実行するトリガーの代わりにいわゆる名前を作成できます。
MySQLの機能が制限されるため、残念ながら、これはMySQLでは機能しません。つまり、2つの解決策があります。
- データをより機能的なデータベースに移行します。
- アプリケーションを変更します。
次の例は、最初の選択肢の可能な解決方法を示しています。私は、Oracle 10gR2で例をテストしました。
一時データ用のテーブルを作成します。現在の値は の値で、その終わりはNULLです。ユニーク制約 は、テーブルに複数の現在の値が含まれないようにします。 テーブルにはプライマリキーがありません。これは、IDが では一時テーブルではユニークではなく、従来のビューでのみ一意であるためです。
CREATE TABLE temporal (
id NUMBER NOT NULL,
starting TIMESTAMP NOT NULL,
ending TIMESTAMP,
attribute CHAR(20),
UNIQUE (id, ending));
レガシーアプリケーションのビューを作成します。
CREATE VIEW legacy (id, attribute) AS
SELECT id, attribute FROM temporal WHERE ending IS NULL;
時間テーブルに 正しい挿入を行う従来のテーブルのトリガ「の代わりに」作成。 レガシーテーブルへの挿入も、一時テーブルへの挿入です。
CREATE TRIGGER legacy_insert
INSTEAD OF INSERT ON legacy
FOR EACH ROW
BEGIN
INSERT INTO temporal (id, starting, ending, attribute)
VALUES (:NEW.id, CURRENT_TIMESTAMP, NULL, :NEW.attribute);
END;
レガシーテーブルの更新のために「代わりに」トリガを作成します。 レガシーテーブルの更新は、 一時テーブルの更新と挿入です。現在の値が更新され、新しい 値に対して新しい行が挿入されます。
CREATE TRIGGER legacy_update
INSTEAD OF UPDATE ON legacy
FOR EACH ROW
BEGIN
UPDATE temporal SET ending = CURRENT_TIMESTAMP WHERE id = :NEW.id;
INSERT INTO temporal (id, starting, ending, attribute)
VALUES (:NEW.id, CURRENT_TIMESTAMP, NULL, :NEW.attribute);
END;
レガシーテーブル内の属性の削除のためのトリガーを「の代わりに」を作成します。レガシーテーブルの削除は、 一時テーブルの更新です。
CREATE TRIGGER legacy_delete
INSTEAD OF DELETE ON legacy
FOR EACH ROW
BEGIN
UPDATE temporal SET ending = CURRENT_TIMESTAMP
WHERE id = :OLD.id AND ending IS NULL;
END;
試してください。
INSERT INTO legacy (id, attribute) VALUES (1, 'a');
SELECT * FROM legacy;
SELECT * FROM temporal;
更新してください。
UPDATE legacy SET attribute = 'A' WHERE id = 1;
SELECT * FROM legacy;
SELECT * FROM temporal;
お試しください。
DELETE FROM legacy WHERE id = 1;
SELECT * FROM legacy;
SELECT * FROM temporal;