SQL Server - создайте один триггер, который запускается для ВСЕХ таблиц в базе данных - PullRequest
6 голосов
/ 24 августа 2011

Я пытаюсь создать триггер в SQL Server 2005, который работает на INSERT, UPDATE и DELETE, но для ВСЕХ таблиц в базе данных (для целей аудита).Возможно ли это сделать?

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

Я знаю, что можно создавать триггеры базы данных, но, похоже, единственные события, которые я могу подключить, связаны с изменениями схемы в таблицах, sprocs и т. Д., Но не для вставок и обновлений записей, если я что-то упустил?

Ответы [ 2 ]

8 голосов
/ 24 августа 2011

Универсальных триггеров таблиц в SQL не существует, поэтому вам нужно будет пройтись по каждой из ваших таблиц (INFORMATION_SCHEMA.Tables) и создать триггеры для каждой из них, используя динамический SQL. (Или придумайте другой простой процесс для создания триггеров для каждой таблицы.)

2 голосов
/ 30 марта 2013
SET NOCOUNT ON;

DECLARE 
    @cr VARCHAR(2) = CHAR(13) + CHAR(10),
    @t  VARCHAR(1) = CHAR(9),
    @s  NVARCHAR(MAX) = N'';

;WITH t AS

(
    SELECT [object_id], 
     s = OBJECT_SCHEMA_NAME([object_id]),
     n = OBJECT_NAME([object_id])
    FROM sys.tables WHERE is_ms_shipped = 0     
)

SELECT @s += 'IF OBJECT_ID(''dbo.ioTrigger_' + t.s + '_' + t.n + ''') IS NOT NULL
    DROP TRIGGER [dbo].[ioTrigger_' + t.s + '_' + t.n + '];
G' + 'O
CREATE TRIGGER ioTrigger_' + t.s + '_' + t.n + '
    ON ' + QUOTENAME(t.s) + '.' + QUOTENAME(t.n) + '
    INSTEAD OF INSERT
AS 
BEGIN
    SET NOCOUNT ON;

-- surely you must want to put some other code here?

    INSERT ' + QUOTENAME(t.s) + '.' + QUOTENAME(t.n) + '
    (
' + 
(
    SELECT @t + @t + name + ',' + @cr
        FROM sys.columns AS c
        WHERE c.[object_id] = t.[object_id]
        AND is_identity = 0
        AND is_rowguidcol = 0
        AND is_computed = 0
    AND system_type_id <> 189
    FOR XML PATH(''), TYPE
).value('.[1]', 'NVARCHAR(MAX)') + '--' 
+ @cr + @t + ')'
+ @cr + @t + 'SELECT 
' + 
(
    SELECT @t + @t + name + ',' + @cr
        FROM sys.columns AS c
        WHERE c.[object_id] = t.[object_id]
        AND is_identity = 0
        AND is_rowguidcol = 0
        AND is_computed = 0
    AND system_type_id <> 189
    FOR XML PATH(''), TYPE
).value('.[1]', 'NVARCHAR(MAX)') + '--'
+ @cr + @t + 'FROM
        inserted;
END' + @cr + 'G' + 'O' + @cr
FROM t
ORDER BY t.s, t.n;

SELECT @s = REPLACE(@s, ',' + @cr + '--' + @cr, @cr);

- вы можете проверить хотя бы часть скрипта, запустив в текстовом режиме - следующее:

SELECT @s;

- если вы хотите увидеть больше всего (ноне обязательно - все), запустите это в режиме сетки и нажмите на результат:

SELECT CONVERT(XML, @s);

исходная страница:

...