我有许多触发器,我想使用通配符构建一个表列表,然后通过向触发器添加一些列名来更新它们的现有触发器。每个触发器中的列名都相同,但我不清楚如何构建表列表或如何在单个 alter trigger 语句中循环列表。我想我将不得不使用光标....
2 回答
没有魔杖可以说“添加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';
无论如何,一旦您对脚本进行了所有必要的调整,您就可以运行它。比扩展每个表并为这些触发器生成脚本要容易得多。
除了 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