I\'ve created this stored procedure which dynamically creates the same trigger for all my tables:
USE [MyDatabase]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIE
create or alter procedure mypro
@msg varchar(20)
as
print(@msg)
go;
exec mypro @msg='fft';
Incorrect syntax near 'go'
Started executing query at Line 1
Msg 102, Level 15, State 1, Procedure mypro, Line 6
Incorrect syntax near 'go'.
;
after go it will work.create or alter procedure mypro
@msg varchar(20)
as
print(@msg)
go;
exec mypro @msg='fft';
[12:17:59 pm] Started executing query at Line 1
Commands completed successfully.
[12:17:59 pm] Started executing query at Line 7
fft
Total execution time: 00:00:00.062
You must execute each part of command in single exec()
command.
Try this:
CREATE PROCEDURE sp_CreateDataChangedTrigger
-- Add the parameters for the stored procedure here
@TableName varchar(255),
@TableKey varchar(255),
@Debug bit=1
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
DECLARE @SQLPart1 varchar(max);
DECLARE @SQLPart2 varchar(max);
SET @SQLPart1 = '
--Drop Trigger
BEGIN TRY
DROP TRIGGER [dbo].[TR_' + @TableName + '_Audit]
END TRY
BEGIN CATCH
END CATCH
'
SET @SQLPart2 = '
--Create Trigger
CREATE TRIGGER [dbo].[TR_' + @TableName + '_Audit]
ON [dbo].[' + @TableName + ']
AFTER INSERT, UPDATE, DELETE
AS
BEGIN
SET NOCOUNT ON
DECLARE @event_type [char]
--Get Event Type
IF EXISTS(SELECT * FROM INSERTED)
IF EXISTS(SELECT * FROM DELETED)
SELECT @event_type = ''U''
ELSE
SELECT @event_type = ''I''
ELSE
IF EXISTS(SELECT * FROM deleted)
SELECT @event_type = ''D''
ELSE
--no rows affected - cannot determine event
SELECT @event_type = ''K''
IF @event_type IN (''I'',''U'') BEGIN
DECLARE @CurrentUserID INT;
SELECT @CurrentUserID = u.UserID
FROM [dbo].[dim_Users] u
WHERE u.[Username] = dbo.udfUserName()
UPDATE t
SET DateModified = GETDATE(),
WhoModifiedID = @CurrentUserID
FROM INSERTED e
JOIN [dbo].[' + @TableName + '] t ON e.[' + @TableKey + '] = t.[' + @TableKey + ']
END
IF @event_type = ''D'' BEGIN
no_op: --Nothing for now
END
END
';
IF @Debug=1 BEGIN
set nocount on;
print @SQLPart1;
print @SQLPart2;
END
ELSE BEGIN
exec(@SQLPart1);
exec(@SQLPart2);
END
END
GO
The error says what the problem is exactly. You are creating a dynamic sql statement to be run all at once by the EXEC
statement. GO
is a batch separator for use in a command line interface or SSMS. It separates multiple statements to be executed separately. Therefore, you cannot have GO
in query statements to be executed by EXEC
or sp_executesql
.
Simply remove the GO
statement, or create two queries to be run by two EXEC
statements.
1) EXEC[UTE]
can execute only T-SQL statements.
GO
is not T-SQL statement.
GO is not a Transact-SQL statement; it is a command recognized by the sqlcmd and osql utilities and SQL Server Management Studio Code editor. SQL Server utilities interpret GO as a signal that they should send the current batch of Transact-SQL statements to an instance of SQL Server.
2) You could replace
SET @SQL = '
--Drop Trigger
BEGIN TRY
DROP TRIGGER [dbo].[TR_' + @TableName + '_Audit]
END TRY
BEGIN CATCH
END CATCH
GO
--Create Trigger
CREATE TRIGGER [dbo].[TR_' + @TableName + '_Audit]
with
DECLARE @TriggerName SYSNAME;
SET @TriggerName = 'TR_' + @TableName + '_Audit';
IF EXISTS (
SELECT *
FROM sys.triggers
WHERE parent_id = OBJECT_ID(@TableName)
AND name = @TriggerName
)
BEGIN
SET @SQL = N'DROP TRIGGER [dbo].' + QUOTENAME(@TriggerName);
EXEC(@SQL);
END
SET @SQL = '
--Create Trigger
CREATE TRIGGER [dbo].[TR_' + @TableName + '_Audit]
or (better)
with
DECLARE @TriggerName SYSNAME;
SET @TriggerName = 'TR_' + @TableName + '_Audit';
IF NOT EXISTS (
SELECT *
FROM sys.triggers
WHERE parent_id = OBJECT_ID(@TableName)
AND name = @TriggerName
)
BEGIN
SET @SQL = N'CREATE TRIGGER [dbo].' + QUOTENAME(@TriggerName) + 'ON ' + @TableName + ' AFTER INSERT, UPDATE, DELETE AS BEGIN SELECT NULL END';
EXEC(@SQL);
END
SET @SQL = '
--Alter Trigger
ALTER TRIGGER [dbo].[TR_' + @TableName + '_Audit]
Note: The object's name should be NVARCHAR(128)
or SYSNAME
.