毎回テンプレートから起こしているのが面倒になったので、一括生成用プロシージャを作ってみた。システム管理テーブルから、トリガ一覧の取得やテーブルの項目一覧取得などを使っているので、ちょちょいと変更していけば結構使いではある・・・かもw
--
--全てのテーブルにてIDENTITY値を調整するためのDELETEトリガを再生成する
--
ALTER PROCEDURE UP_CREATE_ALLDELETETRIGGER
AS
BEGIN--ワーク設定
DECLARE @EXECUTESQL NVARCHAR(MAX);
DECLARE @CRLF NVARCHAR(2);
SET @CRLF = CHAR(13) + CHAR(10);--現在のトリガ一覧を取得
DECLARE @OLDTRIGGERNAME NVARCHAR(MAX);
DECLARE @TRIGGERCOUNT INT;
DECLARE CUR_TRG CURSOR LOCAL FORWARD_ONLY FOR
SELECT
ST.NAME,
(SELECT COUNT(*) FROM SYS.TRIGGER_EVENTS STE2 WHERE STE2.OBJECT_ID = ST.OBJECT_ID) TRIGGERCOUNT
FROM
SYS.TRIGGERS ST
INNER JOIN SYS.TRIGGER_EVENTS STE ON (ST.OBJECT_ID = STE.OBJECT_ID)
WHERE
ST.PARENT_CLASS = 1 AND --対象の親 :DML トリガ用のオブジェクトまたは列
ST.TYPE = 'TR' AND --対象の種類 :トリガ(TR)
STE.TYPE = 3 AND --イベント種類:DELETE時
ST.NAME NOT LIKE '%#__FULLTEXT' ESCAPE '#' AND --フルテキスト用トリガの除外
ST.NAME NOT LIKE '%#__SEARCH' ESCAPE '#' --検索データ用トリガの除外
GROUP BY
ST.OBJECT_ID,
ST.NAME
ORDER BY
ST.NAME
;--既存トリガの削除
OPEN CUR_TRG;
FETCH NEXT FROM CUR_TRG INTO @OLDTRIGGERNAME, @TRIGGERCOUNT;WHILE (@@FETCH_STATUS = 0)
BEGIN
--DELETE時のみのトリガを削除
IF @TRIGGERCOUNT = 1
BEGIN
SET @EXECUTESQL = 'DROP TRIGGER ' + @OLDTRIGGERNAME + '' + @CRLF;
EXECUTE (@EXECUTESQL);
END;FETCH NEXT FROM CUR_TRG INTO @OLDTRIGGERNAME, @TRIGGERCOUNT;
END;CLOSE CUR_TRG;
DEALLOCATE CUR_TRG;--テーブル一覧、IDENTITY列一覧を取得
DECLARE @TABLENAME NVARCHAR(MAX);
DECLARE @COLUMNNAME NVARCHAR(MAX);
DECLARE CUR_IDENT CURSOR LOCAL FORWARD_ONLY FOR
SELECT
ST.NAME,
SC.NAME
FROM
SYS.COLUMNS SC
INNER JOIN SYS.TABLES ST ON (SC.OBJECT_ID = ST.OBJECT_ID)
WHERE
SC.IS_IDENTITY = 1
ORDER BY
ST.NAME, SC.NAME
;--新トリガの生成
OPEN CUR_IDENT;
FETCH NEXT FROM CUR_IDENT INTO @TABLENAME, @COLUMNNAME;WHILE (@@FETCH_STATUS = 0)
BEGIN
--トリガSQLを生成
SET @EXECUTESQL = 'CREATE TRIGGER TRG_DEL_' + @TABLENAME + @CRLF
+ ' ON ' + @TABLENAME + @CRLF
+ ' AFTER DELETE ' + @CRLF
+ 'AS ' + @CRLF
+ 'BEGIN ' + @CRLF
+ ' ' + @CRLF
+ ' SET NOCOUNT ON;' + @CRLF
+ ' ' + @CRLF
+ ' DECLARE @COUNT INT;' + @CRLF
+ ' SET @COUNT = 0;' + @CRLF
+ ' SELECT @COUNT = COUNT(*) FROM DELETED;' + @CRLF
+ ' IF @COUNT <= 0' + @CRLF
+ ' RETURN;' + @CRLF
+ ' ' + @CRLF
+ ' DECLARE @MAXIDENT INT; ' + @CRLF
+ ' SELECT @MAXIDENT = MAX(' + @COLUMNNAME + ') FROM ' + @TABLENAME + ' WITH (UPDLOCK);' + @CRLF
+ ' IF @MAXIDENT IS NULL ' + @CRLF
+ ' SET @MAXIDENT = 0;' + @CRLF
+ ' DBCC CHECKIDENT (''' + @TABLENAME + ''', RESEED, @MAXIDENT) WITH NO_INFOMSGS; ' + @CRLF
+ ' ' + @CRLF
+ 'END; ' + @CRLF;
EXECUTE (@EXECUTESQL);FETCH NEXT FROM CUR_IDENT INTO @TABLENAME, @COLUMNNAME;
END;CLOSE CUR_IDENT;
DEALLOCATE CUR_IDENT;END;
0 件のコメント:
コメントを投稿