作为一些管理任务的一部分,我们有许多表,每个表都需要创建触发器。当对象被修改时,触发器将在审计数据库中设置一个标志和日期。为简单起见,我有一个表,其中包含需要创建触发器的所有对象。
我正在尝试为每个对象生成一些动态 sql 来执行此操作,但出现此错误:
'CREATE TRIGGER' must be the first statement in a query batch.
这是生成sql的代码。
CREATE PROCEDURE [spCreateTableTriggers]
AS
BEGIN
DECLARE @dbname varchar(50),
@schemaname varchar(50),
@objname varchar(150),
@objtype varchar(150),
@sql nvarchar(max),
@CRLF varchar(2)
SET @CRLF = CHAR(13) + CHAR(10);
DECLARE ObjectCursor CURSOR FOR
SELECT DatabaseName,SchemaName,ObjectName
FROM Audit.dbo.ObjectUpdates;
SET NOCOUNT ON;
OPEN ObjectCursor ;
FETCH NEXT FROM ObjectCursor
INTO @dbname,@schemaname,@objname;
WHILE @@FETCH_STATUS=0
BEGIN
SET @sql = N'USE '+QUOTENAME(@dbname)+'; '
SET @sql = @sql + N'IF EXISTS (SELECT * FROM sys.triggers WHERE object_id = OBJECT_ID(N'''+QUOTENAME(@schemaname)+'.[Tiud_'+@objname+'_AuditObjectUpdates]'')) '
SET @sql = @sql + N'BEGIN DROP TRIGGER '+QUOTENAME(@schemaname)+'.[Tiud_'+@objname+'_AuditObjectUpdates]; END; '+@CRLF
SET @sql = @sql + N'CREATE TRIGGER '+QUOTENAME(@schemaname)+'.[Tiud_'+@objname+'_AuditObjectUpdates] '+@CRLF
SET @sql = @sql + N' ON '+QUOTENAME(@schemaname)+'.['+@objname+'] '+@CRLF
SET @sql = @sql + N' AFTER INSERT,DELETE,UPDATE'+@CRLF
SET @sql = @sql + N'AS '+@CRLF
SET @sql = @sql + N'IF EXISTS(SELECT * FROM Audit.dbo.ObjectUpdates WHERE DatabaseName = '''+@dbname+''' AND ObjectName = '''+@objname+''' AND RequiresUpdate=0'+@CRLF
SET @sql = @sql + N'BEGIN'+@CRLF
SET @sql = @sql + N' SET NOCOUNT ON;'+@CRLF
SET @sql = @sql + N' UPDATE Audit.dbo.ObjectUpdates'+@CRLF
SET @sql = @sql + N' SET RequiresUpdate = 1'+@CRLF
SET @sql = @sql + N' WHERE DatabaseName = '''+@dbname+''' '+@CRLF
SET @sql = @sql + N' AND ObjectName = '''+@objname+''' '+@CRLF
SET @sql = @sql + N'END' +@CRLF
SET @sql = @sql + N'ELSE' +@CRLF
SET @sql = @sql + N'BEGIN' +@CRLF
SET @sql = @sql + N' SET NOCOUNT ON;' +@CRLF
SET @sql = @sql + @CRLF
SET @sql = @sql + N' -- Update ''SourceLastUpdated'' date.'+@CRLF
SET @sql = @sql + N' UPDATE Audit.dbo.ObjectUpdates'+@CRLF
SET @sql = @sql + N' SET SourceLastUpdated = GETDATE() '+@CRLF
SET @sql = @sql + N' WHERE DatabaseName = '''+@dbname+''' '+@CRLF
SET @sql = @sql + N' AND ObjectName = '''+@objname+''' '+@CRLF
SET @sql = @sql + N'END; '+@CRLF
--PRINT(@sql);
EXEC sp_executesql @sql;
FETCH NEXT FROM ObjectCursor
INTO @dbname,@schemaname,@objname;
END
CLOSE ObjectCursor ;
DEALLOCATE ObjectCursor ;
END
如果我使用PRINT
并将代码粘贴到新的查询窗口,代码执行没有任何问题。
我已经删除了这些GO
陈述,因为这也给出了错误。
我错过了什么?
为什么我使用EXEC(@sql);
or even时出现错误EXEC sp_executesql @sql;
?
这与里面的上下文有关EXEC()
吗?
非常感谢您的帮助。