SQL Server在数据库触发器中获取表名

时间:2018-04-16 20:09:59

标签: sql sql-server triggers

我想使用数据库级DDL触发器来记录我的数据库中的操作。 我需要获取表名和操作(插入,更新,删除)并将其写入包含日志的表中。

我可以在数据库级触发器中获取表名并使用它来插入表名吗? 或者需要在所有表上放置触发器?

1 个答案:

答案 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/SchemaNameOutput处提取对象(表格)对象和架构{1}}节点。

关于Martin的下面关于OP的评论的后续行动,DDL triger只会触发DDL事件,即/EVENT_INSTANCE/ObjectNameCREATEALTER等命令。对于DROPINSERTUPDATE等DML事件,会触发。所以,如果那就是你需要的,那么这个答案是行不通的,是的,你需要在每张桌子上都有一个触发器。