【发布时间】:2018-04-16 20:09:59
【问题描述】:
我想使用数据库级 DDL 触发器来记录我的数据库中的操作。 我需要获取表名和操作(插入、更新、删除)并将其与日志一起写入表中。
我可以在数据库级触发器中获取表名并使用它来插入表名吗? 还是需要在所有表上放置触发器?
【问题讨论】:
-
你说的是 DDL 触发器,然后给出三个 DML 动作。
标签: sql sql-server triggers
我想使用数据库级 DDL 触发器来记录我的数据库中的操作。 我需要获取表名和操作(插入、更新、删除)并将其与日志一起写入表中。
我可以在数据库级触发器中获取表名并使用它来插入表名吗? 还是需要在所有表上放置触发器?
【问题讨论】:
标签: sql sql-server triggers
这是我在许多数据库中使用的设置。它展示了您询问的大部分内容:
SET ANSI_NULLS ON
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [Meta].[DdlEvents](
[ID] [int] IDENTITY(1,1) NOT NULL,
[CreatedOn] [datetime] NULL,
[CreatedBy] [sysname] NULL,
[CreateBy2] [sysname] NULL,
[SchemaName] [sysname] NULL,
[ObjectName] [sysname] NULL,
[HostName] [sysname] NULL,
[ProgramName] [sysname] NULL,
[SqlCommand] [nvarchar](max) NULL,
[XmlData] [xml] NULL
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
CREATE TRIGGER [DDLTrigger_LogDDL]
ON DATABASE
FOR DDL_DATABASE_LEVEL_EVENTS
AS
BEGIN
SET NOCOUNT ON;
DECLARE
@EventData XML = EVENTDATA();
INSERT INTO Meta.DdlEvents(
SqlCommand,
SchemaName,
ObjectName,
HostName,
ProgramName,
XmlData
)
VALUES (
@EventData.value('(/EVENT_INSTANCE/TSQLCommand)[1]', 'NVARCHAR(MAX)'),
@EventData.value('(/EVENT_INSTANCE/SchemaName)[1]', 'NVARCHAR(255)'),
@EventData.value('(/EVENT_INSTANCE/ObjectName)[1]', 'NVARCHAR(255)'),
HOST_NAME(),
PROGRAM_NAME(),
@EventData
);
END
GO
ENABLE TRIGGER [DDLTrigger_LogDDL] ON DATABASE
GO
具体来说,您使用数据库 DDL 触发器中的 EVENTDATA() 函数来获取事件 XML,然后您可以在 /EVENT_INSTANCE/SchemaName 和 /EVENT_INSTANCE/ObjectName 节点处提取对象(表的)对象和架构。
跟进 Martin 在下面对 OP 的评论,DDL 触发器仅在 DDL 事件上触发,即像 CREATE、ALTER 和 DROP 这样的命令。对于INSERT、UPDATE 和DELETE 等DML 事件,它不会 触发。所以,如果这是你需要的,那么这个答案就行不通了,是的,你需要在每个表上都有一个触发器。
【讨论】: