我有一个正确执行的存储过程。现在,我尝试添加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以了解错误和事务以进行回滚。你认为这有道理吗?
另外,我根据您的评论更改了我的脚本。你怎么看 ?
答案 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语句;