我的数据库上有一个数据库触发器,用于在创建/更改过程时使用EventData审核过程。
我想知道是否有任何方法可以通过“SlipStreaming”修改过程定义将注释行修改为过程定义的结尾?无需:禁用触发器,从EVENTDATA中的DDL定义创建动态SQL字符串,将相关的注释行附加到动态SQL,执行Dynimc SQL以更新proc,然后再次启用触发器......
任何想法?
答案 0 :(得分:0)
不需要禁用触发器,因为SQL Server默认情况下不允许触发器触发自身(这由RECURSIVE_TRIGGERS
数据库选项控制,默认情况下该选项处于关闭状态。因此,您可以从触发器进行DDL修改而不必担心触发自己 - 但您要做的是验证您是否没有被另一个触发器触发,因为这可能导致循环。为此,请使用TRIGGER_NESTLEVEL
。
以下是边缘有点粗糙,但它应该让你开始。特别是,您可能希望自定义注释。此外,检测修改标记是否已经存在是不确定的(但如果您不介意堆叠注释,则可能不需要它)。您可以考虑在存储过程中添加/更改extended property,而不是以文本方式修改它。
AFTER CREATE_PROCEDURE, ALTER_PROCEDURE
AS
BEGIN
SET ARITHABORT ON;
SET NOCOUNT ON;
IF TRIGGER_NESTLEVEL() > 1 RETURN;
PRINT CONVERT(NVARCHAR(MAX), EVENTDATA());
DECLARE @DatabaseName NVARCHAR(128);
SET @DatabaseName = EVENTDATA().value(
'(/EVENT_INSTANCE/DatabaseName)[1]', 'NVARCHAR(128)'
);
DECLARE @Schema NVARCHAR(128);
SET @Schema = EVENTDATA().value(
'(/EVENT_INSTANCE/SchemaName)[1]', 'NVARCHAR(128)'
);
DECLARE @Name NVARCHAR(128);
SET @Name = EVENTDATA().value(
'(/EVENT_INSTANCE/ObjectName)[1]', 'NVARCHAR(128)'
);
DECLARE @Definition NVARCHAR(MAX);
SELECT @Definition =
OBJECT_DEFINITION(
OBJECT_ID(
QUOTENAME(@DatabaseName) + '.' +
QUOTENAME(@Schema) + '.' +
QUOTENAME(@Name),
'P'
)
)
;
SELECT @Definition = STUFF(
@Definition,
CHARINDEX('CREATE', @Definition),
LEN('CREATE'),
'ALTER'
);
IF @Definition NOT LIKE '%--Hacked by Chinese' BEGIN;
SET @Definition += CHAR(13) + CHAR(10) + '--Hacked by Chinese';
EXEC (@Definition);
END;
END;
GO
ENABLE TRIGGER [TR_TweakStoredProcedures] ON DATABASE