Sql server 在EXEC中使用GO时会导致错误:";靠近'的语法不正确;转到&x27&引用;

Sql server 在EXEC中使用GO时会导致错误:";靠近'的语法不正确;转到&x27&引用;,sql-server,tsql,sql-server-express,Sql Server,Tsql,Sql Server Express,我创建了这个存储过程,它为我的所有表动态创建相同的触发器: USE [MyDatabase] GO SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO --Drop Stored Procedure BEGIN TRY DROP PROCEDURE [dbo].[sp_CreateDataChangedTrigger] END TRY BEGIN CATCH END CATCH GO --Create Stored Procedur

我创建了这个存储过程,它为我的所有表动态创建相同的触发器:

USE [MyDatabase]
GO

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

--Drop Stored Procedure
BEGIN TRY
     DROP PROCEDURE [dbo].[sp_CreateDataChangedTrigger]
END TRY
BEGIN CATCH
END CATCH
GO

--Create Stored Procedure

-- ================================================
-- Template generated from Template Explorer using:
-- Create Procedure (New Menu).SQL
--
-- Use the Specify Values for Template Parameters 
-- command (Ctrl-Shift-M) to fill in the parameter 
-- values below.
--
-- This block of comments will not be included in
-- the definition of the procedure.
-- ================================================

-- =============================================
-- Author:      Scott Bass
-- Create date: 06JUL2014
-- Description: Create Data Change triggers
-- =============================================
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 @SQL varchar(max);

     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]
     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
GO
';

     IF @Debug=1 BEGIN
          set nocount on;
          print @SQL;
     END
     ELSE BEGIN
          exec(@SQL);
     END    
END
GO
如果使用调试选项调用SP:

SET NOCOUNT ON;

DECLARE @return_value int

EXEC    @return_value = [dbo].[sp_CreateDataChangedTrigger]
        @TableName = N'dim_Status',
        @TableKey = N'StatusID',
        @Debug = 1

SELECT  'Return Value' = @return_value

GO
然后从“消息”窗口提交结果,效果良好

但是,当我关闭@Debug开关时,会收到以下错误消息:

味精102,第15级,状态1,第10行
“GO”附近的语法不正确。
味精111,第15级,状态1,第13行
“CREATE TRIGGER”必须是查询批处理中的第一条语句。
味精102,第15级,状态1,第51行
“GO”附近的语法不正确


谢谢…

您必须在单个
exec()
命令中执行命令的每个部分

试试这个:

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

您必须在单个
exec()
命令中执行命令的每个部分

试试这个:

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
1)
EXEC[UTE]
只能执行T-SQL语句

GO

GO不是Transact-SQL语句;这是一个由用户识别的命令 sqlcmd和osql实用程序以及sqlserver管理工作室代码 编辑SQL Server实用程序将GO解释为他们应该 将当前批Transact-SQL语句发送到的实例 SQL Server

2) 你可以代替

     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]

或(更好)

注意:对象的名称应为
NVARCHAR(128)
SYSNAME
1)
EXEC[UTE]
只能执行T-SQL语句

GO

GO不是Transact-SQL语句;这是一个由用户识别的命令 sqlcmd和osql实用程序以及sqlserver管理工作室代码 编辑SQL Server实用程序将GO解释为他们应该 将当前批Transact-SQL语句发送到的实例 SQL Server

2) 你可以代替

     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]

或(更好)


注意:对象的名称应为
NVARCHAR(128)
SYSNAME

错误说明了问题的确切原因。您正在创建一个动态sql语句,以便由
EXEC
语句一次运行
GO
是一个批处理分隔符,用于命令行界面或SSM。它将要单独执行的多个语句分隔开。因此,在查询语句中不能有要由
EXEC
sp_executesql
执行的
GO

只需删除
GO
语句,或创建两个由两个
EXEC
语句运行的查询。

错误说明了问题的确切原因。您正在创建一个动态sql语句,以便由
EXEC
语句一次运行
GO
是一个批处理分隔符,用于命令行界面或SSM。它将要单独执行的多个语句分隔开。因此,在查询语句中不能有要由
EXEC
sp_executesql
执行的
GO
。 只需删除
GO
语句,或者创建两个由两个
EXEC
语句运行的查询。

我遇到了相同的错误,我是如何解决的
创建或更改程序mypro
@msg varchar(20)
作为
打印(@msg)
去;
exec mypro@msg='fft';
“go”附近的输出
语法不正确

删除
开始后,它将工作。
创建或更改程序mypro
@msg varchar(20)
作为
打印(@msg)
去;
exec mypro@msg='fft';
[12:17:59 pm]开始在第1行执行查询
命令已成功完成。
[12:17:59 pm]开始在第7行执行查询
快速傅里叶变换
总执行时间:00:00:00.062
我遇到了同样的错误,我是如何修复的
创建或更改程序mypro
@msg varchar(20)
作为
打印(@msg)
去;
exec mypro@msg='fft';
“go”附近的输出
语法不正确

删除
开始后,它将工作。
创建或更改程序mypro
@msg varchar(20)
作为
打印(@msg)
去;
exec mypro@msg='fft';
[12:17:59 pm]开始在第1行执行查询
命令已成功完成。
[12:17:59 pm]开始在第7行执行查询
快速傅里叶变换
总执行时间:00:00:00.062
    Started executing query at Line 1   
    Msg 102, Level 15, State 1, Procedure mypro, Line 6
    Incorrect syntax near 'go'.