2013-12-09 6 views
0

У меня возникла проблема с настройкой триггера ALL SERVER. Я использую базу данных Adventureworks2012, чтобы попытаться запустить триггер аудита. Я хотел бы, чтобы в идеале триггер записывался в базу данных, которую я буду вызывать под названием audit2012, если кто-либо обновляет, вставляет или удаляет на уровне БД.SQL Server 2012 ALL SERVER Проблема с триггером

Я сделал простой триггер, который пишет в таблицу, когда я обновляю и т. Д. Моя проблема в том, когда я пытаюсь изменить его на ВСЕ сервер. Вот SQL. Если я изменяю цель для всех серверов я получаю ошибку:

Msg 1098, Level 15, State 1, Procedure EmpTrig, Line 4
The specified event type(s) is/are not valid on the specified target object.

Код:

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

Вы пытаетесь создать триггер ALL SERVER, который захватывает действия на уровне таблицы. Это невозможно - увидеть список событий, которые можно здесь:

DDL Events (MSDN)

Это звучит, как вы должны смотреть в auditing вместо этого, если вы хотите, чтобы глобально захватить все вставки, обновления и удаления. Существует множество статей и руководств, которые могут помочь вам в этом.

Если вы не можете использовать аудит из-за ограничений издания, то вы можете создать триггер для каждой таблицы. Вы можете автоматизировать создание этих триггеров, например.

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; 
+0

Я использую SQL Server 2012 Express и вынужден ограничивать это использованием. Можно ли обойтись без аудита. Я просмотрел аудит, но сделать аудит не экспресс, а также я пытался использовать профилировщики, но неплатежи мне не очень полезны. Есть ли что-нибудь еще, что я могу сделать, чтобы захватить события DDL? –

+1

Я бы создал триггер для каждой таблицы, которую вы хотите проверить. Невозможно захватить события DML (вставки, обновления и удаления не являются событиями DDL) на уровне сервера. –