0

テーブル内の特定の列が更新され、同じテーブル内の別の列が更新された場合に電子メールを送信する Oracle DB トリガーのリンクまたは例を誰かが提供できますか?

例: テーブルに複数の問題があり、「追加された問題」と「送信済みメール」の 2 つの列があり、デフォルトで「0」になっている

Issue Added    Email Sent
     0             0

「追加された問題」列が「1」に更新されたとき

Issue Added    Email Sent
     1             0

トリガーがメールを送信し、「送信済みメール」列を更新します

Issue Added    Email Sent
     1             1
4

1 に答える 1

1

通常、トリガーで電子メールを送信しようとするのはお勧めできません。

  1. システムが電子メールを送信できない場合 (SMTP サーバーが一時的にダウンしているなどの理由で)、トリガーは失敗し、トリガーステートメントは失敗してロールバックされます。電子メールを送信できなかったという理由だけで、基になるトランザクションを本当に停止したいということはほとんどありません。
  2. 電子メールの送信は非トランザクションです。つまり、コミットされない変更についてメールを送信することになります。INSERTまた、Oracle は書き込みの一貫性を維持するためにステートメントのすべてまたは一部をロールバックして再実行することを選択するため、電子メールを複数回送信することになります。

通常、電子メールを送信する必要がある行を定期的に検索し、電子メールを送信してから、テーブルを更新するデータベース ジョブを使用すると、はるかに優れたサービスが提供されます。古いDBMS_JOBパッケージ、または新しいより洗練されたDBMS_SCHEDULERパッケージのいずれかを使用できます。の線に沿った何か

CREATE OR REPLACE PROCEDURE process_issues
AS
BEGIN
  FOR i IN (SELECT * 
              FROM your_table_name
             WHERE issue_added = 1
               AND email_sent  = 0)
  LOOP
    send_email( i.issue_id );
    UPDATE your_table_name
       SET email_sent = 1
     WHERE issue_id   = i.issue_id;
  END LOOP;
END;

これは、たとえば 5 分ごとに実行されるようにスケジュールされています (DBMS_SCHEDULERパッケージを使用することもできます) 。

DECLARE
  l_jobno PLS_INTEGER:
BEGIN
  dbms_job.submit( l_jobno,
                   'BEGIN process_issues; END;',
                   sysdate + interval '5' minute,
                   'sysdate + interval ''5'' minute' );
  commit;
END;

UTL_MAIL パッケージを使用して、プロシージャを実装できsend_emailます。おそらく、適切なパラメーターを使用して呼び出す必要があるだけです(パラメーターを構成し、ユーザーにパッケージへの適切なアクセス権と、その SMTP サーバーとの通信を可能にする ACL へのアクセス権が付与されているとUTL_MAIL.SEND仮定します)。SMTP_OUT_SERVERUTL_MAIL

于 2012-04-23T15:54:33.370 に答える