【问题标题】:SQL Server get table name in database triggerSQL Server在数据库触发器中获取表名
【发布时间】:2018-04-16 20:09:59
【问题描述】:

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

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

【问题讨论】:

  • 你说的是 DDL 触发器,然后给出三个 DML 动作。

标签: sql sql-server triggers


【解决方案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

具体来说,您使用数据库 DDL 触发器中的 EVENTDATA() 函数来获取事件 XML,然后您可以在 /EVENT_INSTANCE/SchemaName/EVENT_INSTANCE/ObjectName 节点处提取对象(表的)对象和架构。


跟进 Martin 在下面对 OP 的评论,DDL 触发器仅在 DDL 事件上触发,即像 CREATEALTERDROP 这样的命令。对于INSERTUPDATEDELETE 等DML 事件,它不会 触发。所以,如果这是你需要的,那么这个答案就行不通了,是的,你需要在每个表上都有一个触发器。

【讨论】:

  • 如果我正确理解了这个问题,他们会问他们是否可以有一个全局 DML 触发器,可以在任何表的 INSERT、UPDATE、DELETE 上触发
  • @MartinSmith 啊。是的,这不起作用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-26
  • 1970-01-01
  • 1970-01-01
  • 2011-07-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多