T-SQL 安装/升级脚本作为事务
Posted
技术标签:
【中文标题】T-SQL 安装/升级脚本作为事务【英文标题】:T-SQL install / upgrade script as a transaction 【发布时间】:2013-02-22 15:17:47 【问题描述】:我正在尝试编写一个 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 放入事务块中?什么可以进入交易块有什么限制?或者,有什么比我想要实现的更好的选择?
谢谢
【问题讨论】:
你打算这样做多少次? 只有一次升级... 您应该能够将所有 DDL 语句包装在一个大事务中,尽管如前所述,您必须删除任何GO
语句。我还建议您在开始之前备份您的数据库 - 这样您就可以选择超级回滚语句RESTORE DATABASE
。
【参考方案1】:
正如 Thomas Haratyk 在他的回答中所说,您的问题是“去”。但是,您可以在事务中拥有任意数量的批次。不喜欢这样的是 try/catch。这是一个简单的概念验证:
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
【讨论】:
【参考方案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?
Using "GO" within a transaction
http://msdn.microsoft.com/en-us/library/ms188037.aspx
【讨论】:
我已经尝试删除GO
,但是我在下一个BEGIN
块上遇到语法错误,这导致大量其他语法错误链接到脚本末尾!
看我的编辑,创建过程如果没有嵌入动态sql需要是第一条语句
这是否允许多个EXEC
statments?
是的,您可以在交易中使用多个 EXEC以上是关于T-SQL 安装/升级脚本作为事务的主要内容,如果未能解决你的问题,请参考以下文章
如何升级已在 Linux 上生产的 Solr 5 版本(作为服务安装)?
Tableau server 日常维护13 Tableau server 升级