如何使用Microsoft SQL Server Management Studio为数据库中的所有触发器生成脚本

我想生成一个包含SQL的SQL脚本来创build我们的数据库中存在的所有触发器。 触发器直接通过SSMS查询窗格添加,因此除了数据库本身的触发器之外,目前没有其他来源。

我已经尝试了右键单击数据库的方法,select“ Tasks->Generate Scripts然后使用“脚本整个数据库和所有对象”选项。 虽然这会为表和约束创build一个SQL脚本,但不会为触发器生成SQL。

我也明白,我可以右键单击数据库中的每个触发器,然后select“生成SQL脚本”选项,但目前在审计(插入,更新和删除)下有46个表。

而是手动为46个表中的每一个生成插入,更新和删除触发器脚本,有没有更简单的方法来做到这一点? 或者,我应该开始点击,复制和粘贴?

数据库 – >任务 – >生成脚本 – >下一步 – >下一步

select脚本选项 UI,在表格/视图选项标题下,将脚本触发器设置为True

在这里输入图像说明

在这里输入图像说明

我知道答案已经被接受了,但是当SSMS向导无法为触发器生成脚本时(在我的情况下,它是MSSQL2008R2)

这个解决scheme基于上面dana的想法,但是如果它超过4000个字符(限制'syscomments'视图的'text'列),则使用'sql_modules'来提供触发器的完整代码。

 select [definition],'GO' from sys.sql_modules m inner join sys.objects obj on obj.object_id=m.object_id where obj.type ='TR' 

右键单击结果网格,然后“保存结果为…”保存到保存格式的文件中

这个怎么样?

select text from syscomments where text like '%CREATE TRIGGER%'

编辑 – 根据jj的评论下面, syscomments已被弃用,将来会被删除。 请使用上面列出的基于向导或基于脚本的解决scheme前进:)

要脚本所有触发器,您可以定义存储过程:

 SET ansi_nulls ON GO SET quoted_identifier ON GO -- Procedure: -- [dbo].[Createscriptofalltriggers] -- -- Parameter: -- @InclDrop bit -- possible values: -- 0 - Script to drop the triggers is not generated. -- 1 - Script to drip the triggers is generated. ALTER PROCEDURE [dbo].[Createscriptofalltriggers] @InclDrop BIT =1 AS DECLARE @SQL VARCHAR(8000), @Text NVARCHAR(4000), @BlankSpaceAdded INT, @BasePos INT, @CurrentPos INT, @TextLength INT, @LineId INT, @MaxID INT, @AddOnLen INT, @LFCR INT, @DefinedLength INT, @SyscomText NVARCHAR(4000), @Line NVARCHAR(1000), @UserName SYSNAME, @ObjID INT, @OldTrigID INT SET nocount ON SET @DefinedLength = 1000 SET @BlankSpaceAdded = 0 IF @InclDrop <> 0 SET @InclDrop =1 -- This Part Validated the Input parameters DECLARE @Triggers TABLE ( username SYSNAME NOT NULL, trigname SYSNAME NOT NULL, objid INT NOT NULL ) DECLARE @TrigText TABLE ( objid INT NOT NULL, lineid INT NOT NULL, linetext NVARCHAR(1000) NULL ) INSERT INTO @Triggers (username, trigname, objid) SELECT DISTINCT A.NAME, B.NAME, B.id FROM dbo.sysusers A, dbo.sysobjects B, dbo.syscomments C WHERE A.uid = B.uid AND B.type = 'Tr' AND B.id = C.id AND C.encrypted = 0 IF EXISTS(SELECT C.* FROM syscomments C, sysobjects O WHERE O.id = C.id AND O.type = 'Tr' AND C.encrypted = 1) BEGIN PRINT '/*' PRINT 'The following encrypted triggers were found' PRINT 'The procedure could not write the script for it' SELECT DISTINCT A.NAME, B.NAME, B.id FROM dbo.sysusers A, dbo.sysobjects B, dbo.syscomments C WHERE A.uid = B.uid AND B.type = 'Tr' AND B.id = C.id AND C.encrypted = 1 PRINT '*/' END DECLARE ms_crs_syscom CURSOR local forward_only FOR SELECT T.objid, C.text FROM @Triggers T, dbo.syscomments C WHERE T.objid = C.id ORDER BY T.objid, C.colid FOR READ only SELECT @LFCR = 2 SELECT @LineId = 1 OPEN ms_crs_syscom SET @OldTrigID = -1 FETCH next FROM ms_crs_syscom INTO @ObjID, @SyscomText WHILE @@fetch_status = 0 BEGIN SELECT @BasePos = 1 SELECT @CurrentPos = 1 SELECT @TextLength = Len(@SyscomText) IF @ObjID <> @OldTrigID BEGIN SET @LineID = 1 SET @OldTrigID = @ObjID END WHILE @CurrentPos != 0 BEGIN --Looking for end of line followed by carriage return SELECT @CurrentPos = Charindex(Char(13) + Char(10), @SyscomText, @BasePos) --If carriage return found IF @CurrentPos != 0 BEGIN WHILE ( Isnull(Len(@Line), 0) + @BlankSpaceAdded + @CurrentPos - @BasePos + @LFCR ) > @DefinedLength BEGIN SELECT @AddOnLen = @DefinedLength - ( Isnull(Len(@Line), 0 ) + @BlankSpaceAdded ) INSERT @TrigText VALUES ( @ObjID, @LineId, Isnull(@Line, N'') + Isnull(Substring(@SyscomText, @BasePos, @AddOnLen), N'')) SELECT @Line = NULL, @LineId = @LineId + 1, @BasePos = @BasePos + @AddOnLen, @BlankSpaceAdded = 0 END SELECT @Line = Isnull(@Line, N'') + Isnull(Substring(@SyscomText, @BasePos, @CurrentPos -@BasePos + @LFCR), N'') SELECT @BasePos = @CurrentPos + 2 INSERT @TrigText VALUES( @ObjID, @LineId, @Line ) SELECT @LineId = @LineId + 1 SELECT @Line = NULL END ELSE --else carriage return not found BEGIN IF @BasePos <= @TextLength BEGIN /*If new value for @Lines length will be > then the **defined length */ WHILE ( Isnull(Len(@Line), 0) + @BlankSpaceAdded + @TextLength - @BasePos + 1 ) > @DefinedLength BEGIN SELECT @AddOnLen = @DefinedLength - ( Isnull(Len(@Line), 0 ) + @BlankSpaceAdded ) INSERT @TrigText VALUES ( @ObjID, @LineId, Isnull(@Line, N'') + Isnull(Substring(@SyscomText, @BasePos, @AddOnLen), N'')) SELECT @Line = NULL, @LineId = @LineId + 1, @BasePos = @BasePos + @AddOnLen, @BlankSpaceAdded = 0 END SELECT @Line = Isnull(@Line, N'') + Isnull(Substring(@SyscomText, @BasePos, @TextLength -@BasePos+1 ), N'') IF Len(@Line) < @DefinedLength AND Charindex(' ', @SyscomText, @TextLength + 1) > 0 BEGIN SELECT @Line = @Line + ' ', @BlankSpaceAdded = 1 END END END END FETCH next FROM ms_crs_syscom INTO @ObjID, @SyscomText END IF @Line IS NOT NULL INSERT @TrigText VALUES( @ObjID, @LineId, @Line ) CLOSE ms_crs_syscom PRINT '-- You should run this result under dbo if your triggers belong to multiple users' PRINT '' IF @InclDrop = 1 BEGIN PRINT '-- Dropping the Triggers' PRINT '' SELECT 'If exists(Select * from sysObjects where id =Object_ID(''[' + username + '].[' + trigname + ']'') and ObjectProperty(Object_ID(''[' + username + '].[' + trigname + ']''), ''ISTRIGGER'')=1) Drop Trigger [' + username + '].[' + trigname + '] ' + Char(13) + Char(10) + 'GO' + Char(13) + Char(10) + Char(13) + Char(10) FROM @Triggers END PRINT '----------------------------------------------' PRINT '-- Creation of Triggers' PRINT '' PRINT '' DECLARE ms_users CURSOR local forward_only FOR SELECT T.username, T.objid, Max(D.lineid) FROM @Triggers T, @TrigText D WHERE T.objid = D.objid GROUP BY T.username, T.objid FOR READ only OPEN ms_users FETCH next FROM ms_users INTO @UserName, @ObjID, @MaxID WHILE @@fetch_status = 0 BEGIN PRINT 'SetUser N''' + @UserName + '''' + Char(13) + Char(10) SELECT '-- Text of the Trigger'= CASE lineid WHEN 1 THEN 'GO' + Char(13) + Char( 10) + linetext WHEN @MaxID THEN linetext + 'GO' ELSE linetext END FROM @TrigText WHERE objid = @ObjID ORDER BY lineid PRINT 'Setuser' FETCH next FROM ms_users INTO @UserName, @ObjID, @MaxID END CLOSE ms_users PRINT 'GO' PRINT '------End ------' DEALLOCATE ms_crs_syscom DEALLOCATE ms_users GO 

如何执行它:

 SET nocount ON DECLARE @return_value INT EXEC @return_value = [dbo].[Createscriptofalltriggers] @InclDrop = 1 SELECT 'Return Value' = @return_value 

使用syscomments可能不总是工作。 syscomments的文本列被限制为4000个字符。 超过的触发器将被截断。 您可能无法完全查看。

实际上,如果您查看sys.comments表,它有一个colid字段是一个数字列; 如果它长于最大值,那么数字> 1。 如果你要select一个大于1的colID,并复制两个(如果有2个logging),它会给你整个触发!