我正在尝试编写一个T-SQL脚本,该脚本将升级当前正在部署的系统。该脚本将包含以下内容的混合:
由于这是一个相当大的升级,我希望脚本在其单个部分失败时回滚。我在下面概述了我的尝试代码:
DECLARE @upgrade NVARCHAR(32);
SELECT @upgrade = 'my upgrade';
BEGIN TRANSACTION @upgrade
BEGIN
PRINT 'Starting';
BEGIN TRY
CREATE TABLE x ( --blah...
);
ALTER TABLE y --blah...
);
CREATE PROCEDURE z AS BEGIN ( --blah...
END
GO --> this is causing trouble!
CREATE FUNCTION a ( --blah...
END TRY
BEGIN CATCH
PRINT 'Error with transaction. Code: ' + @@ERROR + '; Message: ' + ERROR_MESSAGE();
ROLLBACK TRANSACTION @upgrade;
PRINT 'Rollback complete';
RETURN;
END TRY
END
PRINT 'Upgrade successful';
COMMIT TRANSACTION @upgrade;
GO
注意 - 我知道一些语法并不完美 - 我不得不重新键入代码
似乎我无法将存储过程放入事务块中。是否有一个原因?是因为使用了GO
这个词吗?如果是这样,我如何将SP放入事务块?什么可以进入事务块有什么限制?或者,什么是我想要实现的更好的替代方案?
由于
答案 0 :(得分:3)
正如Thomas Haratyk在回答中所说,你的问题是“走了”。但是,您可以根据需要在事务中拥有尽可能多的批次。这是尝试/捕获不喜欢这个。这是一个简单的概念验证:
begin tran
go
select 1
go
select 2
go
rollback
begin try
select 1
go
select 2
go
end try
begin catch
select 1
end catch
答案 1 :(得分:2)
删除GO并使用动态sql创建程序,否则将失败。
EXEC ('create procedure z
as
begin
print "hello world"
end')
GO不是SQL关键字,它是批处理分隔符。所以它不能包含在交易中。
请参阅这些主题以获取更多信息:
sql error:'CREATE/ALTER PROCEDURE' must be the first statement in a query batch?