sql-而不是触发器不会从视图中触发基表

Posted

技术标签:

【中文标题】sql-而不是触发器不会从视图中触发基表【英文标题】:sql- instead of trigger doesnt trigger on basetable from view 【发布时间】:2011-06-23 17:45:16 【问题描述】:

当新数据插入到 BASETABLE 中时,我希望它使 View (InsteadView) 的触发器将数据插入到不同的表中。它仅在我将数据手动插入视图时有效,但在我将数据插入基表时无效。

CREATE TABLE BaseTable
  (PrimaryKey     int PRIMARY KEY IDENTITY(1,1),
   Color          nvarchar(10) NOT NULL,
   Material       nvarchar(10) NOT NULL,
   ComputedCol AS (Color + Material)
  )
GO

--Create a view that contains all columns from the base table.
CREATE VIEW InsteadView
AS SELECT PrimaryKey, Color, Material, ComputedCol
FROM BaseTable
GO

--Create an INSTEAD OF INSERT trigger on the view.
CREATE TRIGGER InsteadTrigger on InsteadView
INSTEAD OF INSERT
AS
BEGIN
  --Build an INSERT statement ignoring inserted.PrimaryKey and 
  --inserted.ComputedCol.
  INSERT INTO anotherTable
       SELECT Color, Material
       FROM inserted
END
GO

插入基表(颜色, 材料) 值(N'Red',N'Cloth')

--查看INSERT语句的结果。 选择主键、颜色、 Material, ComputedCol FROM another table

【问题讨论】:

观点是什么? 这是一个简单的例子。真实视图由 15 个表组成。如果我能做到这一点,它将帮助我解决真正的问题。 【参考方案1】:

这是按设计工作的。用非数据库术语重申您的问题“我给前门把手通电,但每当我走进后门时,我都不会感到震惊,只有当我走进前门时才会感到震惊。”如果您希望在打开后门时获得同样的电击,那么也将后门通电。

触发器是在视图上定义的,因此当您向其中插入数据时,它会关闭。基本表上没有定义任何内容,因此没有触发器触发。在基表上放置一个而不是触发器将导致它将数据推送到备用表中,但是您永远不会将数据放入其中(除非您执行一些血腥的黑客攻击,例如添加另一列并根据值执行条件逻辑)。

【讨论】:

那么为什么会有人想要使用 Intead of 触发器呢?我不想手动将数据插入到我的视图中。我希望它在我的基表增长时增长,并且在每次插入时触发器写入另一个表。 当基表增长时,你希望你的视图“变大”是什么意思?视图只不过是一个“已保存”的查询。如果您需要修改对象(表/视图)但又不想担心重构调用代码,则触发器很有用。调用者和 db 之间的合同仍然有效,但在幕后,触发器将数据推送到 NewTable 而不是旧的。至少,这是我必须使用它们的场景。我敢肯定其他人有不同的用例。 如果 basetable 有 20 行,那么我创建的 View 也将有 20 行。因此,假设我还有 5 个表,并且视图连接了它们的行。然后还应用了一些算法。现在我希望该视图中的新数据写入新表。你明白为什么这很重要吗?为什么我需要在每次插入时从视图中取出数据? 我正在努力摸索你。该视图由多个表 T1 到 Tn(连接或联合)组成。将第 21 行添加到 T1/basetable 应该反映在 w 视图中(除非由于过滤器/连接而被消除)。插入视图的数据应该写入 Tn+1 吗?写入 T1 的行应该转到 Tn 吗?我们要解决的问题是什么? 我认为几乎在同一页面上。表中的数据反映在视图中。我的目标是每次将新数据写入表时,视图中的相同数据都会写入不同的表。在我的真实数据库中,视图由具有许多计算的多个表组成,因此数据对我来说比其原始表中的数据更有意义。如何创建代替触发器以将数据从视图获取到不同的表?

以上是关于sql-而不是触发器不会从视图中触发基表的主要内容,如果未能解决你的问题,请参考以下文章

SQL 视图

简述oracle视图

而不是所有表上的插入触发器

视图基表中的 SQL 更新行

SQL而不是触发器有时不会触发?

您能否在视图上编写触发器,该视图在更改其基表后利用插入和删除表中的数据?