0

ワイルドカードを使用してテーブルのリストを作成し、いくつかの列名をトリガーに追加して既存のトリガーを更新したいトリガーがたくさんあります。列名は各トリガーで同じになりますが、テーブルのリストを作成する方法や、単一のトリガー変更ステートメントでリストをループする方法がわかりません。カーソルを使用する必要があると思います....

4

2 に答える 2

1

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

とにかく、スクリプトに必要なすべての調整を行ったら、スクリプトを実行するだけです。すべてのテーブルを展開してそれらのトリガー用のスクリプトを生成するよりもはるかに簡単です。

于 2012-06-24T01:22:40.623 に答える
0

一貫性のないオブジェクト命名規則を持つ一連の複雑なトリガーでうまく機能した 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
于 2012-06-24T14:03:35.393 に答える