2

我有一个 SQL Server 2008 数据库。有三个端子连接到它(A、B、C)。数据库中有一个表SampleTable,它对任何终端活动作出反应。每次登录到此数据库的任何终端上有一些活动时,新行都会插入到SampleTable.

我想将来自三个终端中的一个 (C) 的流量重定向到表 RealTable 而不是 SampleTable,但我必须在 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

对您来说最简单的解决方案之一是 INSTEAD OF 触发器。简单地说,它是在您决定的操作上“触发”并让您“覆盖”该操作的默认行为的触发器。

您可以使用 INSTEAD OF 触发器覆盖特定表/视图的 INSERT、DELETE 和 UPDATE 语句(您经常将它与组合来自不同表的数据的视图一起使用,并且您希望使视图可插入),您可以在其中放置您的逻辑. 在触发器内部,您可以在适当的时候再次调用 INSERT,并且您不必担心递归 - INSTEAD OF 触发器不会应用于触发器代码本身内部的语句。

享受。

于 2013-03-25T13:13:43.433 回答