顧客と営業担当者間の取り引きを取り消すには、Policy テーブルのローを削除します。この例の Policy テーブルの変更内容は、以前の営業担当者に正しくレプリケートされます。ただし、Customers テーブルは変更されません。このため、Customers テーブルに対する変更は、以前の営業担当者にレプリケートされません。
トリガがない場合は、Customers テーブルに不正確なデータを持つサブスクライバが残される可能性があります。Policy テーブルに新しいローを追加する場合にも、同様の問題が発生します。
この解決法としては、Policy テーブルに変更が行われたときに起動する BEFORE トリガを記述します。この特別なトリガでは、データベース・テーブルは変更されませんが、サブスクライバ・データベースでのデータ管理用に SQL Remote が使用するトランザクション・ログに、エントリが作成されます。
たとえば、次の文では、Policy テーブルに対する挿入を追跡する BEFORE INSERT トリガを作成し、リモート・データベースに適切なデータが含まれることを保証します。
CREATE TRIGGER InsPolicy BEFORE INSERT ON Policy REFERENCING NEW AS NewRow FOR EACH ROW BEGIN UPDATE Customers PUBLICATION SalesRepData SUBSCRIBE BY ( SELECT rep_key FROM Policy WHERE cust_key = NewRow.cust_key UNION ALL SELECT NewRow.rep_key ) WHERE cust_key = NewRow.cust_key; END; |
次の文では、Policy テーブルからの削除を追跡する BEFORE DELETE トリガを作成します。
CREATE TRIGGER DelPolicy BEFORE DELETE ON Policy REFERENCING OLD AS OldRow FOR EACH ROW BEGIN UPDATE Customers PUBLICATION SalesRepData SUBSCRIBE BY ( SELECT rep_key FROM Policy WHERE cust_key = OldRow.cust_key AND Policy_key <> OldRow.Policy_key ) WHERE cust_key = OldRow.cust_key; END; |
UPDATE PUBLICATION 文の SUBSCRIBE BY 句にはサブクエリが含まれており、このサブクエリは複数の値を返すことができます。
UPDATE PUBLICATION 文の SUBSCRIBE 句に含まれているサブクエリは UNION 式であり、複数の値を返すことができます。
... SELECT rep_key FROM Policy WHERE cust_key = NewRow.cust_key UNION ALL SELECT NewRow.rep_key ... |
UNION 式の最初の部分は、Policy テーブルから取得した、顧客と取り引きする既存の営業担当者のセットです。
サブスクリプション・クエリの結果セットには、新しい営業担当者だけでなく、ローを受信する営業担当者全員が含まれている必要があります。
UNION 式の 2 番目の部分は、INSERT 文から取得した、顧客と取り引きする新しい営業担当者の rep_key 値です。
BEFORE DELETE トリガ内のサブクエリは、複数の値を返します。
... SELECT rep_key FROM Policy WHERE cust_key = OldRow.cust_key AND rep_key <> OldRow.rep_key ... |
サブクエリは、Policy テーブルから rep_key の値を取得します。削除される値 (AND rep_key <> OldRow.rep_key) を除き、移動される顧客 (WHERE cust_key = OldRow.cust_key) と取り引きする営業担当者全員のプライマリ・キー値が、その値に含まれます。
サブスクリプション・クエリの結果セットには、削除に続くローを受信する営業担当者と一致した値のすべてが含まれている必要があります。
Customers テーブルのデータは、(プライマリ・キーの値などによって) 個々のサブスクライバと関連付けられることはなく、複数のサブスクライバ間で共有されます。このため、レプリケーション・メッセージ間の複数のリモート・サイトでデータが更新される可能性があり、レプリケーションの競合が発生することがあります。(特定のユーザだけに Customers テーブルの更新権を付与するなどの方法で) パーミッションを使用するか、データベースに RESOLVE UPDATE トリガを追加してプログラム上で競合を処理することによって、この問題に対処できます。
Policy テーブル上の更新については、ここでは説明していません。そのような操作は避けるか、例で示したように、BEFORE INSERT と BEFORE DELETE の各トリガの機能を組み合わせる BEFORE UPDATE トリガを作成する必要があります。
Copyright © 2009, iAnywhere Solutions, Inc. - SQL Anywhere 11.0.1 |