已阅读this page,我已经建立了几个表和一个触发器。这个想法是,当在第一个表INSERT
上执行UPDATE
,DELETE
或Matt
时,所操作的数据将被插入第二个审计表{{ 1}}。
触发器一定失败了,我不知道为什么;有证据表明,尽管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
在Matt上触发:
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]
以下insert语句会将行插入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
触发器中我缺少什么或出错了?
答案 0 :(得分:2)
我认为问题是因为这样的:
FROM
inserted i
INNER JOIN deleted d ON i.MattID = d.MattID;
INSERTED
中有记录。DELETED
中的记录。INSERTED
(新值)和DELETED
(旧值)中的记录。将两者结合在一起将始终为INSERT
或DELETE
产生0行,因为进行INSERT时,INSERTED
中将有1行或更多行,而{{ 1}}。反之亦然,DELETED
语句。
我的建议是将单个触发器分为每种情况(DELETE
,INSERT
和UPDATE
)的触发器,并在每个新触发器中都有一个查询
一个小警告是DELETE
触发器将在AFTER UPDATE
和INSERTED
表中添加行。
在运行UPDATE查询之前,DELETED
中的值将是已放置的值,而INSERTED
中的值将是旧值。
答案 1 :(得分:0)
我认为您正在执行的错误是在插入和删除的表之间进行内部联接。 2表中的MattId决不能相同。我的意思是,您应该像左或右进行外部联接(或在2个不同的选择中加载变量,而不是执行1个)。试试看,希望您理解我!