0

我在设置 ALL SERVER 触发器时遇到问题。我正在使用 Adventureworks2012 数据库来尝试使审核触发器正常工作。理想情况下,如果有人在数据库级别进行更新、插入或删除,我希望将触发器写入一个名为 audit2012 的数据库。

我做了一个简单的触发器,当我更新等时写入表。我的问题是当我尝试将其更改为所有服务器时。这是SQL。如果我将目标更改为 ALL SERVER,则会收到错误消息:

消息 1098,级别 15,状态 1,过程 EmpTrig,第 4 行
指定的事件类型在指定的目标对象上无效。

代码:

USE [AdventureWorks2012]
GO
/****** Object:  Trigger [HumanResources].[EmpTrig]    
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TRIGGER [HumanResources].[EmpTrig]
ON ALL SERVER
FOR UPDATE, DELETE, INSERT
AS
BEGIN

    -- Insert statements for trigger here

    update [HumanResources].[Employee] set JobTitle = 'UPDATE TRIGGER' where BusinessEntityID = 290

END

感谢您的帮助。

4

1 回答 1

3

您正在尝试创建一个捕获表级操作的 ALL SERVER 触发器。这是不可能的 - 请参阅此处可能发生的事件列表:

DDL 事件 (MSDN)

如果您想全局捕获所有插入、更新和删除,听起来您应该研究审计。有很多文章和教程可以帮助你解决这个问题。

如果由于版本限制而无法使用审计,那么您可以在每个表上创建一个触发器。您可以自动创建这些触发器,例如

  DECLARE @sql NVARCHAR(MAX) = N'';

  SELECT @sql += N'
  CREATE TRIGGER ' + QUOTENAME(s.name) + '.Audit_' 
    + s.name + '_' + t.name
    + ' ON ' + QUOTENAME(s.name) + '.' + QUOTENAME(t.name)
    + ' FOR INSERT, UPDATE, DELETE
    AS 
    BEGIN
      INSERT dbo.AuditTable([table], [action], ... other auditing columns ...)
        SELECT ''' + QUOTENAME(s.name) + '.' + QUOTENAME(t.name) + ''',
          CASE WHEN EXISTS (SELECT 1 FROM inserted) THEN
            CASE WHEN EXISTS (SELECT 1 FROM deleted) THEN ''update''
            ELSE ''insert'' END 
          ELSE ''delete'' END, ... other auditing information ...;
    END
    GO'
    FROM sys.tables AS t
    INNER JOIN sys.schemas AS s
    ON t.[schema_id] = s.[schema_id];

  PRINT @sql;
  -- EXEC sp_executesql @sql;
于 2013-12-09T14:44:10.983 回答