ワイルドカードを使用してテーブルのリストを作成し、いくつかの列名をトリガーに追加して既存のトリガーを更新したいトリガーがたくさんあります。列名は各トリガーで同じになりますが、テーブルのリストを作成する方法や、単一のトリガー変更ステートメントでリストをループする方法がわかりません。カーソルを使用する必要があると思います....
2 に答える
this code
「すべてのトリガーに追加する」(または他のオブジェクト タイプに追加する) という魔法の杖はありません。
多くのオブジェクト タイプのバッチ編集では、オブジェクト エクスプローラーの詳細とそのビュー内での並べ替えやフィルター処理を使用して、複数のオブジェクトのスクリプトをすばやく生成できます。たとえば、オブジェクト エクスプローラーで [ストアド プロシージャ] を強調表示すると、それらはすべて [オブジェクト エクスプローラーの詳細] に一覧表示され、複数のオブジェクトを選択して右クリックし、[ストアド プロシージャのスクリプト] を > [作成] > [作成] のように選択できます。
トリガーはテーブルの下にネストされているため、これを行う便利な方法はありません (また、トリガーは、データベースを右クリックして [タスク] > [スクリプトの生成] を選択したときに選択できるエンティティ タイプでもありません)。ただし、メタデータからスクリプトを非常に簡単に取得できます (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';
とにかく、スクリプトに必要なすべての調整を行ったら、スクリプトを実行するだけです。すべてのテーブルを展開してそれらのトリガー用のスクリプトを生成するよりもはるかに簡単です。
一貫性のないオブジェクト命名規則を持つ一連の複雑なトリガーでうまく機能した Aaron の提案に加えて、私は何かを調理しようとしました。楽しみ。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