我想使用数据库级DDL触发器来记录我的数据库中的操作。 我需要获取表名和操作(插入,更新,删除)并将其写入包含日志的表中。
我可以在数据库级触发器中获取表名并使用它来插入表名吗? 或者需要在所有表上放置触发器?
答案 0 :(得分:1)
这是我在许多数据库中使用的设置。它展示了您询问的大部分内容:
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
具体来说,您使用Database DDL触发器中的EVENTDATA()
函数来获取Event XML,然后您可以在/EVENT_INSTANCE/SchemaName
和处提取对象(表格)对象和架构{1}}节点。
关于Martin的下面关于OP的评论的后续行动,DDL triger只会触发DDL事件,即/EVENT_INSTANCE/ObjectName
,CREATE
和ALTER
等命令。对于DROP
,INSERT
和UPDATE
等DML事件,不会触发。所以,如果那就是你需要的,那么这个答案是行不通的,是的,你需要在每张桌子上都有一个触发器。