Go命令错误

时间:2013-09-04 06:41:38

标签: sql sql-server tsql

我有一个正确执行的存储过程。现在,我尝试添加TRY CATCH T-SQL语句。

添加

BEGIN TRY

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
SET XACT_ABORT ON
GO

/****** add new column Accountid  to Metainformation table ******/

IF NOT EXISTS (SELECT * FROM SYSCOLUMNS WHERE NAME = 'Accountid' AND ID = OBJECT_ID('[GSF].[dbo].[Metainformation]'))
BEGIN
    ALTER TABLE [GSF].[dbo].[Metainformation] ADD Accountid int 
END
GO



IF EXISTS (SELECT * FROM SYSCOLUMNS WHERE NAME = 'Accountid' AND ID = OBJECT_ID('[GSF].[dbo].[Metainformation]'))
BEGIN
    UPDATE [GSF].[dbo].[Metainformation]  
    SET MP.Accountid = AD.Accountid
    FROM [GSF].[dbo].[Metainformation] MI, [GSF].[dbo].[AccountDetails] AD
    WHERE MI.DetailID= AD.DetailID
END
GO

我的GO语句中出现错误,显示错误说GO附近的语法不正确。

任何指针或替代品都可以使用?

更新代码:

USE GSF
GO

/****** add new column AccountId  to MetaInformation table ******/
IF NOT EXISTS (SELECT * FROM **SYS.COLUMNS** WHERE NAME = 'AccountId' AND ID = OBJECT_ID('[GSF].[dbo].[MetaInformation]'))
    ALTER TABLE [GSF].[dbo].[MetaInformation] ADD AccountId uniqueidentifier 

BEGIN TRANSACTION;
BEGIN TRY


SET ANSI_NULLS ON
SET QUOTED_IDENTIFIER ON


/****** If the column AccountId exists, Update all the AccountId values in MetaInformation from AccountDetails ******/

IF EXISTS (SELECT * FROM **SYS.COLUMNS** WHERE NAME = 'AccountId' AND ID = OBJECT_ID('[GSF].[dbo].[MetaInformation]'))
BEGIN
    UPDATE MP  
    SET MP.AccountId = AD.AccountId
    FROM [GSF].[dbo].[MetaInformation] MP
    **INNER JOIN**  
    [GSF].[dbo].[AccountDetails] AD
    ON MP.AllocationDetailId = AD.AllocationDetailId
END

/****** Drop AccountId column from AccountDetails ******/

IF EXISTS (SELECT * FROM SYS.COLUMNS WHERE NAME = 'AccountId' AND ID = OBJECT_ID('[GSF].[dbo].[AccountDetails]'))
    ALTER TABLE [GSF].[dbo].[AccountDetails] DROP COLUMN AccountId 


/****** add two new PStage values to [PStageToCategory] table ******/

INSERT INTO [GSF].[dbo].[PStageToCategory]
   (PStage, PStageToCategoryName)
   VALUES(19,1)

INSERT INTO [GSF].[dbo].[PStageToCategory]
   (PStage, PStageToCategoryName)
   VALUES(21,1)



/****** Drop and create new ViewName view to remove reference of AccountId ******/

USE GSF

IF EXISTS ( SELECT * FROM sys.views WHERE name = 'ViewName')
DROP VIEW ViewName


DECLARE @sql_view NVARCHAR(MAX);
SET @sql_view = '<VIEW DEFINITION>';
EXEC sp_executesql @sql_view;

COMMIT TRANSACTION
END TRY

BEGIN CATCH
SELECT
    ERROR_NUMBER() AS ErrorNumber
   ,ERROR_SEVERITY() AS ErrorSeverity
   ,ERROR_STATE() AS ErrorState
   ,ERROR_PROCEDURE() AS ErrorProcedure
   ,ERROR_LINE() AS ErrorLine
   ,ERROR_MESSAGE() AS ErrorMessage;
END CATCH

我正在使用此脚本来更改生产中的模式。因此,如果脚本中存在错误(运行中只有一个错误),则包括尝试catch以了解错误和事务以进行回滚。你认为这有道理吗?

另外,我根据您的评论更改了我的脚本。你怎么看 ?

3 个答案:

答案 0 :(得分:3)

“GO不是Transact-SQL语句;它是由sqlcmd和osql实用程序以及SQL Server Management Studio代码编辑器识别的命令” - 来自MSDN的引用。

下面的示例代码假设您只是从SSMS或其他一个实用程序执行脚本。

以下是对代码的一些改进。

1 - TRY / CATCH代码块需要在一个批次中。因此,GO需要在阻止之后。

2 - SYSCOLUMNS表已折旧,最终将从产品中删除。请参阅有关此主题的Jason Strate's博客文章。

3 - 如果IF表达式后面有一个语句,则不需要BEGIN / END代码块。

4 - 您应该避免使用ANSI 92连接,因为它们在SQL Server 2012中不起作用。有关此主题,请参阅Mike Walsh的博客article

5 - 有一个错误,其中MP.Accountid被用来代替MI.Accountid。

6 - 在语句结尾处使用分号,因为将来会有一些关于此问题的嗡嗡声。

总之,我在编写存储过程时使用TRY / CATCH块,并希望将错误代码返回给调用应用程序。此示例代码仅返回有关错误的信息。

此致

约翰

-- 
-- Use correct database and set session settings
--

-- Switch to correct database
USE [GSF];
GO

-- Change session settings
SET ANSI_NULLS ON;
SET QUOTED_IDENTIFIER ON;
SET XACT_ABORT ON;
GO


--
-- My code block
--

BEGIN TRY

-- Add column if it does not exist
IF NOT EXISTS (SELECT * FROM SYS.COLUMNS AS C WHERE C.NAME = 'Accountid' AND C.OBJECT_ID = OBJECT_ID('dbo.Metainformation'))
    ALTER TABLE [dbo].[Metainformation] ADD Accountid INT;

-- Update the column regardless
IF EXISTS (SELECT * FROM FROM SYS.COLUMNS AS C WHERE C.NAME = 'Accountid' AND C.OBJECT_ID = OBJECT_ID('dbo.Metainformation'))
    UPDATE Metainformation
    SET Accountid = AD.Accountid
    FROM [dbo].[Metainformation] AS MI JOIN [dbo].[AccountDetails] AS AD ON MI.DetailID = AD.DetailID;

END TRY


--
-- My error handling
--

-- Error Handler
BEGIN CATCH
    SELECT
        ERROR_NUMBER() AS ErrorNumber
       ,ERROR_SEVERITY() AS ErrorSeverity
       ,ERROR_STATE() AS ErrorState
       ,ERROR_PROCEDURE() AS ErrorProcedure
       ,ERROR_LINE() AS ErrorLine
       ,ERROR_MESSAGE() AS ErrorMessage;
END CATCH

GO

答案 1 :(得分:0)

确保GO_之后没有空格。 任何空格都会改变关键字GO。因此,在每个GO之后,执行ENTER

答案 2 :(得分:0)

看过你的代码后,我建议你不要使用TRY...CATCH

  

TRY ... CATCH构造不能跨越多个批次[ 1 ]。 TRY ... CATCH构造不能跨越多个Transact-SQL语句块。例如,TRY ... CATCH构造不能跨越Transact-SQL语句的两个BEGIN ... END块,并且不能跨越IF ... ELSE构造。

1 批处理作为单独的命令发送到SQL Server。客户端工具需要知道如何将长脚本分成多个批次以发送到服务器。按照惯例,大多数客户端工具(Management Studio,OSQL等)都使用GO

  

GO不是Transact-SQL语句;