23

メールトリガーを開発しようとしています。使用者がレコードを挿入するときに「速度」フィールドをチェックして、挿入された値が100を超えると、指定されたアドレスにメールが送信されるように、これをどのように達成できるかを誰かが支援できますか.

4

1 に答える 1

52

まず、データベースメールを設定する必要があります。まだ設定していない場合は、次の質問が役立つ場合があります。

次に、トリガーが必要です。

CREATE TRIGGER dbo.whatever
ON dbo.wherever
FOR INSERT
AS
BEGIN
    SET NOCOUNT ON;

    IF EXISTS (SELECT 1 FROM inserted WHERE speed > 100)
    BEGIN
        EXEC msdb.dbo.sp_send_dbmail
          @recipients = 'whoever@yourcompany.com', 
          @profile_name = 'default',
          @subject = 'Someone was speeding', 
          @body = 'Yep, they sure were.';
    END
END
GO

さて、あなたはおそらく、挿入物からのデータを実際に電子メールに含めたいと言うでしょう。そして、最初の傾向は、いくつかのローカル変数を宣言し、それらをから割り当てることですinserted-トリガーが複数行の挿入に応答する可能性があるため、これは機能しません。したがって、これを行う正しい方法は次のとおりです。

CREATE TRIGGER dbo.whatever
ON dbo.wherever
FOR INSERT
AS
BEGIN
    SET NOCOUNT ON;

    DECLARE @body NVARCHAR(MAX) = N'';

    SELECT @body += CHAR(13) + CHAR(10) + RTRIM(some_col) FROM inserted;

    IF EXISTS (SELECT 1 FROM inserted WHERE speed > 100)
    BEGIN
        EXEC msdb.dbo.sp_send_dbmail
          @recipients = 'whoever@yourcompany.com', 
          @profile_name = 'default',
          @subject = 'At least one person was speeding', 
          @body = @body;
    END
END
GO

とはいえ、私はトリガーから電子メールを送信することの大ファンではありません。データベースメールはサービスブローカーを使用するため非同期ですが、キューテーブルにデータを入力し、適切なすべての電子メールを送信するバックグラウンドスレッドを使用する傾向があります。これについての2つの3つの良い点は次のとおりです。

  1. トリガーを起動した外部トランザクションをコミットする際の潜在的な遅延を最小限に抑えます。トリガー内のロジックが複雑になるほど、そのプロセスは遅くなります。
  2. 行が挿入されたマイクロ秒単位で電子メールが送信されることはおそらく必須ではないため、バックグラウンドプロセスのタイミングを簡単に変動させることができます。これにより、1日中、非常に数回しかテーブルをチェックする必要がなくなります。実際に何かをしなければならないことはありません。
  3. @goodeyeが指摘したように、このプロセスを分離しておくと、プロセスの電子メール部分のエラーが元のDMLに干渉するのを防ぐことができます(この場合、無効なパラメーターがsp_send_dbmail挿入を妨げました)。
于 2012-05-25T13:45:28.393 に答える