SQL Server - 创建为数据库中的所有表运行的单个触发器

时间:2011-08-24 10:37:19

标签: sql sql-server sql-server-2005 tsql triggers

我正在尝试在SQL Server 2005中创建一个在INSERT,UPDATE和DELETE上运行的触发器,但是对于数据库中的所有表(用于审计目的)。有可能这样做吗?

目前,我们为数据库中的每个表都有单独的触发器,因为它们都做同样的事情,所以我希望将它们合并为一个触发器。

我知道可以创建数据库触发器,但我可以挂钩的唯一事件似乎是对表,sprocs等的模式更改,但不是对记录的插入和更新,除非我遗漏了什么?

2 个答案:

答案 0 :(得分:8)

SQL中不存在通用表触发器,因此您需要遍历每个表(INFORMATION_SCHEMA.Tables)并使用动态SQL为每个表创建触发器。 (或者提出另一个简单的过程来为每个表创建触发器。)

答案 1 :(得分:2)

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);

source page: