dynamischer SQL-Fehler: 'CREATE TRIGGER' muss die erste Anweisung in einem Abfragebatch sein
Im Rahmen einiger administrativer Aufgaben verfügen wir über viele Tabellen, für die jeweils ein Trigger erstellt werden muss. Der Auslöser setzt ein Flag und das Datum in der Überwachungsdatenbank, an dem ein Objekt geändert wurde. Der Einfachheit halber habe ich eine Tabelle mit allen Objekten, für die Trigger erstellt werden müssen.
Ich versuche, eine dynamische SQL zu generieren, um dies für jedes Objekt zu tun, aber ich erhalte den folgenden Fehler:'CREATE TRIGGER' must be the first statement in a query batch.
Hier ist der Code zum Generieren der SQL.
<code>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 </code>
Wenn ich benutzePRINT
und fügen Sie den Code in ein neues Abfragefenster ein, der Code wird problemlos ausgeführt.
Ich habe das entferntGO
Aussagen wie diese lieferten ebenfalls Fehler.
Was vermisse ich?
Warum erhalte ich einen Fehler bei der Verwendung vonEXEC(@sql);
oder auchEXEC sp_executesql @sql;
?
Hat das etwas mit dem inneren Kontext zu tun?EXEC()
?
Vielen Dank für jede Hilfe.