Sql-Server
編寫數據庫中所有觸發器的腳本
我有一些數據庫作為訂閱者參與複製,它們有觸發器並被一組不同的應用程序使用。
每次我需要重新初始化這些數據庫時,我都需要編寫觸發器、權限和索引的腳本,應用快照,然後重新應用這些觸發器、索引和權限。
是否有一個腳本可以用來編寫目前數據庫的所有觸發器?
這似乎比您擁有的要簡單得多:
CREATE TABLE #tmp ( db sysname, sch sysname, obj sysname, name sysname, is_disabled bit, def nvarchar(max) ); GO INSERT #tmp SELECT DB_NAME(), s.name, o.name, t.name, t.is_disabled, m.definition FROM sys.triggers AS t INNER JOIN sys.sql_modules AS m ON t.object_id = m.object_id INNER JOIN sys.objects AS o ON t.parent_id = o.object_id INNER JOIN sys.schemas AS s ON o.schema_id = s.schema_id WHERE parent_class = 1;
當您準備好再次創建它們時:
DECLARE @sql nvarchar(max) = N''; SELECT @sql += def + CHAR(13) + CHAR(10) + N'GO' + CHAR(13) + CHAR(10) FROM #tmp; SELECT @sql += N'DISABLE TRIGGER ' + QUOTENAME(sch) + N'.' + QUOTENAME(name) + N' ON ' + QUOTENAME(sch) + N'.' + QUOTENAME(obj) + N';' FROM #tmp WHERE is_disabled = 1; PRINT @sql; -- EXEC sys.sp_executesql @sql;
是的,您將無法驗證整個腳本是否存在,因為 SSMS 不會輸出
@sql
. 有關解決方法,請參閱此文章。另外,如果您總是知道要影響的數據庫,我不知道為什麼需要將數據庫作為動態腳本的一部分,但是有一種更安全的方法可以使數據庫名稱動態化,而無需連接值並邀請 SQL 注入:
DECLARE @db sysname = N'AdventureWorks'; DECLARE @exec nvarchar(max), @sql nvarchar(max); SET @exec = QUOTENAME(@db) + N'.sys.sp_executesql'; SET @sql = N'SELECT DB_NAME();'; EXEC @exec @sql;