2

SQLServer2008データベースがあります。それに接続されている3つの端子(A、B、C)があります。SampleTableデータベースには、端末のアクティビティに反応するテーブルがあります。このDBにログオンしている端末で何らかのアクティビティが発生するたびに、新しい行がに挿入されSampleTableます。

3つの端末のうちの1つからのトラフィックを、SampleTableではなくRealTableテーブルに書き込むようにリダイレクトしたいのですが、端末アクティビティをDBに書き込むサービスはブラックボックスにあるため、DBレイヤーでこれを行う必要があります。

リダイレクトロジックで動作しているトリガーがすでにいくつかありますSampleTableが、問題は、行がまだに挿入されていることSampleTableです。

このための最もクリーンなソリューションは何ですか。挿入トリガーで行を削除することは、悪いこと、悪いこと、悪いことだと確信しています。

助けてください。

編集:

現在のロジックは次のようなものです(これは擬似コードです)。

ALTER TRIGGER DiffByTerminal
 ON SampleTable
AFTER INSERT
AS
DECLARE @ActionCode VARCHAR(3), 
    @ActionTime DATETIME,
    @TerminalId INT

  SELECT @ActionCode = ins.ActionCode, 
     @ActionTime = ins.ActionTime, 
     @TerminalId = ins.TerminalId
  FROM inserted ins

IF(@TerminalId = 'C')
BEGIN

    INSERT INTO RealTable 
    (   
         ...
    )
    VALUES
    (
         @ActionCode, 
         @ActionTime, 
         @TerminalId
    )
END
4

2 に答える 2

3

行がテーブルに挿入される前に何かを「インターセプト」するには、INSTEAD OFトリガーではなくトリガーが必要AFTERです。したがって、既存のトリガー(すべての挿入が単一行であると想定した欠陥のあるロジックも含まれています)を削除して、INSTEAD OF代わりにこのトリガーを作成できます。

DROP TRIGGER DiffByTerminal;
GO

CREATE TRIGGER dbo.DiffByTerminal
 ON dbo.SampleTable
INSTEAD OF INSERT
AS
BEGIN
  SET NOCOUNT ON;

  INSERT dbo.RealTable(...) SELECT ActionCode, ActionTime, TerminalID
    FROM inserted
    WHERE TerminalID = 'C';

  INSERT dbo.SampleTable(...) SELECT ActionCode, ActionTime, TerminalID
    FROM inserted
    WHERE TerminalID <> 'C';
END
GO

これは、(a)Cのみ、(b)非Cのみ、および(c)混合で構成される単一行インサートおよび複数行インサートを処理します。

于 2013-03-25T13:21:49.320 に答える
1

最も簡単な解決策の1つは、INSTEADOFトリガーです。簡単に言うと、決定したアクションに「発火」し、アクションのデフォルトの動作を「オーバーライド」できるようにするトリガーです。

INSTEAD OFトリガーを使用して、特定のテーブル/ビューのINSERT、DELETE、およびUPDATEステートメントをオーバーライドできます(異なるテーブルのデータを組み合わせたビューでよく使用し、ビューを挿入可能にします)。ここでロジックを配置できます。 。トリガーの内部では、適切なときにINSERTを再度呼び出すことができ、再帰について心配する必要はありません。INSTEADOFトリガーは、トリガーコード自体の内部からのステートメントには適用されません。

楽しみ。

于 2013-03-25T13:13:43.433 に答える