我有一个SQL Server 2008数据库。有三个端子连接(A,B,C)。数据库中有一个表SampleTable
,它对任何终端活动做出反应。每次在任何终端上都有某些活动,登录到此数据库时,新行将插入SampleTable
。
我想将流量从三个终端中的一个(C)重定向到写入表RealTable而不是SampleTable,但我必须在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
答案 0 :(得分: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)混合。
答案 1 :(得分:1)
最简单的解决方案之一是INSTEAD OF触发器。简单地说,触发器会“触发”您决定的动作,并让您“覆盖”动作的默认行为。
您可以使用INSTEAD OF触发器覆盖特定表/视图的INSERT,DELETE和UPDATE语句(使用组合来自不同表的数据并且您希望使视图可插入的视图),您可以在其中把你的逻辑。在触发器内部,您可以在适当的时候再次调用INSERT,并且您不必担心递归 - INSTEAD OF触发器不会应用于触发器代码本身内部的语句。
享受。