Heroku Connect でのカスタムトリガーの使用
最終更新日 2022年11月29日(火)
カスタムトリガーは正式にサポートされておらず、Heroku サポートで支援を提供することもできません。ご自身の責任でご利用ください。
Heroku Connect では、Connect テーブルの変更を監視して変更を Salesforce に書き込むために Postgres トリガーを使用します。Connect のテーブルで独自のカスタムトリガーを実装すると、負荷が増加し、Connect で更新の取りこぼしが発生する可能性があります。
xmlbinary の理解
Heroku Connect では、xmlbinary
という名前の Postgres 変数を、その独自のトリガーで使用します。xmlbinary
の値によって、更新を Salesforce に送信するかどうかが決まります。Connect ではこの変数によって、その独自の更新が Salesforce に送り返されて無限ループが発生するのを防ぎます。
xmlbinary
の値が base64
の場合、Connect のトリガーは Salesforce に送信する行の更新を検出します。xmlbinary
が hex
の場合、Connect のトリガーは行の更新を無視します。カスタムトリガーでこの値を設定して、Salesforce への更新の送信を一時的に有効または無効にすることができます。
Salesforce からのデータまたは外部テーブルへのデータに応答して変更を行う
Salesforce からの変更に応答するときは、AFTER
トリガーを使用して、xmlbinary
の値を一時的に base64
に変更します。変更を行った後は、以前の値を復元します。これは、捕捉が必要な別のテーブルのデータを変更している場合にもうまく機能します。
次に示すのは、Contact
のマッピングの例です。
Contact
レコードが Salesforce で作成され、通常の同期操作の一環として、Connect によって Heroku Postgres データベースに書き込まれます。- トリガーは、
externalid__c
を持つ Heroku Postgres の行を更新します。 - Heroku Connect はこの更新を検出し、Salesforce に再同期します。
Contact
の例のカスタムトリガーは次のようになります。
CREATE OR REPLACE FUNCTION salesforce.contact_external_id_proc() RETURNS TRIGGER AS $$
DECLARE
oldxmlbinary varchar;
BEGIN
-- Save old value
oldxmlbinary := get_xmlbinary();
-- Change value base64 to ensure writing to _trigger_log is enabled
SET LOCAL xmlbinary TO 'base64';
-- Add your custom trigger code here.
-- Update the external ID
UPDATE salesforce.contact SET externalid__c = gen_random_uuid()
WHERE id = NEW.id;
-- Your custom trigger code ends here.
-- Reset the value
EXECUTE 'SET LOCAL xmlbinary TO ' || oldxmlbinary;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
DROP TRIGGER IF EXISTS contact_after_trigger ON salesforce.contact;
CREATE TRIGGER contact_after_trigger
AFTER INSERT OR UPDATE ON salesforce.contact
FOR EACH ROW
WHEN (get_xmlbinary()::text = 'hex'::text AND NEW.externalid__c IS NULL)
EXECUTE PROCEDURE salesforce.contact_external_id_proc();
Connect では、一度に何千ものレコードを INSERT、UPDATE、または DELETE することはよくあります。ステージング環境でテストを行い、レコードが大量の場合でもカスタムトリガーが正常に動作することを確認してください。これらのトリガーは、レコードの変更ごとの変更の書き込みが多くない場合でも最適に動作します。さらに、複雑な計算よりも単純な計算を使用します。複雑な計算を行うと、Salesforce からのデータの書き込み速度が大幅に低下する可能性があります。
独自のデータ変更ステートメントの結果を変更する
Connect によって捕捉されたデータを、独自の SQL ステートメントに応答する形で変更するには、カスタムトリガーを使用することもできます。たとえば、データベースに新しいレコードを書き込むたびに、UUID 外部 ID が必ず挿入されるようにできます。この場合、BEFORE
トリガーを使用して、元の INSERT ステートメントが Connect によって感知されるようにします。
前のセクションの Contact
の例の続きでは、BEFORE
トリガーは次のようになります。
CREATE OR REPLACE FUNCTION salesforce.contact_external_id__before_proc() RETURNS TRIGGER AS $$
BEGIN
-- Add your custom trigger code here.
-- Update the external ID
NEW.external_id__c := gen_random_uuid();
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
DROP TRIGGER IF EXISTS contact_before_trigger ON salesforce.contact;
CREATE TRIGGER contact_before_trigger
BEFORE INSERT OR UPDATE ON salesforce.contact
FOR EACH ROW
WHEN (get_xmlbinary()::text = 'base64'::text AND NEW.externalid__c IS NULL)
EXECUTE PROCEDURE salesforce.contact_external_id_before_proc();
この場合、xmlbinary
が base64
であることは WHEN
条件によって保証されます。レコードの残りの部分に対する変更を Connect で確実に捕捉するために、その値を設定または設定解除する必要はありません。