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 升级

Linux下使用脚本安装和升级pip

管家婆千方百剂2008升级到千方百计II 脚本执行错误 请检查第69行

Linux MySQL 5.7二进制 小版本升级

CentOS 升级 Python3 (附带: 一键升级脚本)