0

我有许多触发器,我想使用通配符构建一个表列表,然后通过向触发器添加一些列名来更新它们的现有触发器。每个触发器中的列名都相同,但我不清楚如何构建表列表或如何在单个 alter trigger 语句中循环列表。我想我将不得不使用光标....

4

2 回答 2

1

没有魔杖可以说“添加this code到所有触发器”(或任何其他对象类型,就此而言)。

对于许多对象类型,对于批量编辑,您可以使用对象资源管理器详细信息以及该视图中的排序和/或过滤快速生成多个对象的脚本。例如,如果您在对象资源管理器中突出显示“存储过程”,它们都会在对象资源管理器详细信息中列出,您可以选择多个对象,右键单击,并将存储过程编写为 > CREATE To >

由于触发器嵌套在表下,因此没有方便的方法来执行此操作(触发器也不是您可以在右键单击数据库并选择任务 > 生成脚本时选择的实体类型)。但是您可以很容易地从元数据中提取脚本(Results to Text运行时需要在 Management Studio 中):

SET NOCOUNT ON;

SELECT OBJECT_DEFINITION([object_id]) 
  + CHAR(13) + CHAR(10) + 'GO' + CHAR(13) + CHAR(10)
  FROM sys.triggers
  WHERE type = 'TR';

您可以获取输出,将其复制并粘贴到顶部窗格中,然后将新代码添加到每个触发器后,您将需要做更多的工作,例如搜索/'CREATE TRIGGER'替换'ALTER TRIGGER'. 您也可以将其作为查询的一部分进行,但它依赖于具有一致编码约定的创建者。由于某些触发器可能看起来像这样......

create          trigger

...您可能需要用手按摩一些。

如果您只对某组表感兴趣,也可以过滤上面的查询。例如,要仅更改与以Sales您开头的表关联的触发器,可以说:

AND OBJECT_NAME(parent_id) LIKE N'Sales%';

或仅适用于Person架构中的表:

AND OBJECT_SCHEMA_NAME(parent_id) = N'Person';

无论如何,一旦您对脚本进行了所有必要的调整,您就可以运行它。比扩展每个表并为这些触发器生成脚本要容易得多。

于 2012-06-24T01:22:40.623 回答
0

除了 Aarons 的建议,它在一堆具有不一致对象命名约定的复杂触发器上效果很好,然后我尝试做一些事情,这样我就可以记住我在 3 个月内做了什么。享受。创建或更改 SP,然后在没有参数的情况下执行。

CREATE PROCEDURE SP_ALTER_CONTOUR_TRIGS
--sp to bulk edit many triggers at once
--NO ERROR HANDLING!
AS 
    DECLARE
        @sql VARCHAR(500),
        @tableName VARCHAR(128),
        @triggerName VARCHAR(128),
        @tableSchema VARCHAR(128)


    DECLARE triggerCursor CURSOR
        FOR
    SELECT
        so_tr.name AS TriggerName,
        so_tbl.name AS TableName,
        t.TABLE_SCHEMA AS TableSchema
    FROM
        sysobjects so_tr
    INNER JOIN sysobjects so_tbl ON so_tr.parent_obj = so_tbl.id
    INNER JOIN INFORMATION_SCHEMA.TABLES t 
    ON 
        t.TABLE_NAME = so_tbl.name
   WHERE
   --here's where you want to build filters to make sure you're 
   --targeting the trigs you want edited
   --BE CAREFUL!
   --test the select statement first against sysobjects
   --to see that it returns what you expect
        so_tr.type = 'TR'
        and so_tbl.name like '%contours'
        and so_tr.name like'%location_id'

    ORDER BY
        so_tbl.name ASC,
        so_tr.name ASC

    OPEN triggerCursor

    FETCH NEXT FROM triggerCursor 
    INTO @triggerName, @tableName, @tableSchema

    WHILE ( @@FETCH_STATUS = 0 )
        BEGIN
--insert alter statement below
--watch out for cr returns and open and close qoutes!
--seems to act finicky if you don't use schema-bound naming convention
SET @sql = '
ALTER TRIGGER ['+ @tableSchema +'].['
+ @triggerName + '] ON ['+ @tableSchema +'].['
+ @tableName + ']
INSTEAD OF INSERT
AS
BEGIN
SET NOCOUNT ON; 
INSERT ['+ @tableSchema +'].['+ @tableName + '] 
(OBJECTID, Contour, Type, Shape, RuleID, Override)
SELECT 
a.OBJECTID, a.Contour, a.Type, a.Shape, a.RuleID, a.Override
FROM 
(SELECT 
OBJECTID, Contour, Type, Shape, RuleID, Override
FROM inserted)
AS a
END
'


            PRINT 'Executing Statement - '+ @sql
            EXECUTE ( @sql )
            FETCH NEXT FROM triggerCursor 
            INTO @triggerName, @tableName,  @tableSchema
        END

    CLOSE triggerCursor
    DEALLOCATE triggerCursor
于 2012-06-24T14:03:35.393 回答