使用我的数据库升级脚本,我通常只有一个长脚本,可以对该数据库版本进行必要的更改。但是,如果一个语句在脚本中途失败,则会使数据库处于不一致状态。
如何使整个升级脚本进行一次原子操作?我试过在事务中包装所有语句,但这不起作用。即使SET XACT_ABORT为ON,如果一个语句失败并回滚事务,其余的语句就会继续运行。我想要一个不需要我写IF @@ TRANCOUNT>的解决方案。 0 ......在每个陈述之前。例如:
SET XACT_ABORT ON;
GO
BEGIN TRANSACTION;
GO
CREATE TABLE dbo.Customer
(
CustomerID int NOT NULL
, CustomerName varchar(100) NOT NULL
);
GO
CREATE TABLE [dbo].[Order]
(
OrderID int NOT NULL
, OrderDesc varchar(100) NOT NULL
);
GO
/* This causes error and should terminate entire script. */
ALTER TABLE dbo.Order2 ADD
A int;
GO
CREATE TABLE dbo.CustomerOrder
(
CustomerID int NOT NULL
, OrderID int NOT NULL
);
GO
COMMIT TRANSACTION;
GO
答案 0 :(得分:1)
Red-Gate和其他比较工具的工作方式与您描述的完全一样......他们在每个语句后检查@@ ERROR和@@ TRANCOUNT,将其卡入#temp表,最后检查#临时表。如果发生任何错误,它们会回滚事务,否则它们会提交。我相信你可以改变任何工具生成你的更改脚本来添加这种逻辑。 (或者不是重新发明轮子,你可以使用已经为你创建原子脚本的工具。)
答案 1 :(得分:0)