tsql - 用于填充审计表的基本 T-SQL 触发器
问题描述
阅读此页面后,我构建了几个表和一个触发器。这个想法是,当对第一个表执行or时INSERT
,所操作的数据将插入到第二个审计表中。UPDATE
DELETE
Matt
MattAudit
触发器一定失败了,我不知道为什么;证据是审计表中没有任何条目,尽管CREATE TRIGGER
后续ALTER TRIGGER
语句成功完成。
主表Matt
:
CREATE TABLE [dbo].[Matt](
[MattID] [int] IDENTITY(1,1) NOT NULL,
[Text] [nchar](10) NULL,
CONSTRAINT [PK_Matt] PRIMARY KEY CLUSTERED
(
[MattID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
审核表MattAudit
:
CREATE TABLE [dbo].[MattAudit](
[MattAuditID] [int] IDENTITY(1,1) NOT NULL,
[MattID] [int] NOT NULL,
[Text] [nchar](10) NULL,
[Action] [int] NOT NULL,
[InsertedDate] [datetime] NOT NULL,
CONSTRAINT [PK_MattAudit] PRIMARY KEY CLUSTERED
(
[MattAuditID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
触发马特:
ALTER TRIGGER TrgMattAudit ON Matt
AFTER INSERT, UPDATE, DELETE
AS
BEGIN
SET NOCOUNT ON;
INSERT INTO [dbo].[MattAudit]
( MattID, [Text], [Action], InsertedDate )
SELECT
ISNULL(i.MattID, d.MattID) as MattID,
ISNULL(i.Text, d.Text) as Text,
CASE ISNULL(i.MattID,0) WHEN 0 THEN 0 ELSE 1 END
+
CASE ISNULL(d.MattID,0) WHEN 0 THEN 0 ELSE -1 END
as [Action],
GETDATE() as InsertedDate
FROM
inserted i
INNER JOIN deleted d ON i.MattID = d.MattID;
END
下面的插入语句将向表中插入行,Matt
但表中不显示任何内容MattAudit
。
INSERT INTO Matt ([Text]) VALUES ('Test4')
我在触发器中遗漏了什么或出错了?
解决方案
I think the problem is because of this:
FROM
inserted i
INNER JOIN deleted d ON i.MattID = d.MattID;
- When inserting you only have records in
INSERTED
. - When you delete records you only have records in
DELETED
. - When you update records you will have records in both
INSERTED
(new value) andDELETED
(old value).
Joining the two will always result in 0 rows for INSERT
or DELETE
, because when doing an INSERT you will have 1 or more rows in INSERTED
, but 0 rows in DELETED
. And vice versa for the DELETE
statement.
A suggestion I would make is to split the single trigger into a trigger for each situation (INSERT
, UPDATE
and DELETE
) and have a single query in each of your new triggers.
A small caveat is that an AFTER UPDATE
trigger will add rows in both INSERTED
and DELETED
table.
The value in INSERTED
will be the value which was put in place, and the value in DELETED
will be the old value, before the UPDATE query ran.
推荐阅读
- c# - 如何使用 c# VSTO 编写包含 excel 错误的 2D 数据
- joomla - joomla 网站上的受保护方法调用
- css - Woocommerce - 隐藏在小屏幕上的产品图片
- javascript - 使用 Javascript 和 JSON.parse 解析多维数组
- selenium - 启动 Internet Explorer 时出现意外错误。IELaunchURL() 使用 IEDriver Selenium IE11 返回 HRESULT 80070012('没有更多文件。')
- c - 在 C 中访问元素并将其输入到结构的动态数组中
- c# - Windows 锁定模式,而 sendkeys 或鼠标控制 c#
- routes - 堆栈中的英雄 - Flutter
- php - 如何避免运费被添加到 Woocommerce 购物篮内的总金额中?
- google-app-maker - 创建关键字列表 WITHIN Create with MANY to MANY 关系