sql - 在某些条件下禁止插入表

标签 sql database sql-server-2008 triggers insert-into

我有一个 SQL Server 2008 数据库。有三个端子连接到它(A、B、C)。数据库中有一个表SampleTable,它对任何终端事件使用react。每次登录到此数据库的任何终端上有一些事件时,新行都会插入到 SampleTable 中。

我想重定向来自三个终端之一 (C) 的流量以写入表 RealTable 而不是 SampleTable,但我必须在数据库层执行此操作,因为将终端事件写入数据库的服务位于黑匣子中。

我已经有一些触发器在具有重定向逻辑的 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

最佳答案

为了在将行插入表之前“拦截”某些内容,您需要一个 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) 混合。

关于sql - 在某些条件下禁止插入表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15615314/

相关文章:

sql-server - 当在 SQL Server Management Studio 中删除数据库时,所有空间是否都会释放回操作系统?

mysql - 如何使用子查询显示来自多个表的列名

mysql - 如何使用递归公用表表达式删除结果?

sql - 查找特定记录的值(value)相对于整个结果的百分比

database - 如何使用哈希在redis中存储这些数据

php - 如果链接中的 html 等于某内容,我该如何操作链接或链接的父级?

SQL 'like' 表达式匹配所有 varchar 值(即没有完成实际过滤)?

sql - 如何从SQL中的一行中选择奇数或偶数项?

java - 具有分隔值性能的列表

c# - 通过 C# 连接到 SQL Server 2008 数据库