日期:2014-05-17  浏览次数:20547 次

MSSQL2000,显式事务,表中加入一列后能否立即UPDATE为该列付值?
本帖最后由 ltolll 于 2013-02-17 14:49:31 编辑
BEGIN TRAN -- 开始事务
DECLARE @errorNumber int -- 定义错误数变量
SET @errorNumber=0

-- 添加字段:ScoreUnit
IF NOT EXISTS(SELECT * FROM syscolumns WHERE id=object_id('GoodsSort') and name='ScoreUnit')
BEGIN
PRINT '正在创建GoodsSort表的ScoreUnit字段;'
ALTER TABLE GoodsSort ADD ScoreUnit smallint DEFAULT (0) -- 如果ScoreUnit字段不存在则创建
END
SET @errorNumber=@errorNumber+@@error --记录是否发生错误

IF EXISTS(SELECT * FROM syscolumns WHERE id=object_id('GoodsSort') and name='ScoreUnit')
BEGIN
PRINT '正在更新GoodsSort表的ScoreUnit字段;'
UPDATE GoodsSort SET [ScoreUnit]=100 --各类商品皆为100元积1分
END
SET @errorNumber=@errorNumber+@@error --记录是否发生错误

 -- 根据是否产生错误决定事务是提交还是撤销
 IF (@errorNumber > 0)
 BEGIN 
   PRINT '事务处理失败,回滚事务!'
   ROLLBACK TRAN 
 END 
 ELSE
 BEGIN
   PRINT '事务处理成功,提交事务!'
   COMMIT TRAN
 END

执行报错:
服务器: 消息 207,级别 16,状态 1,行 1
列名 'ScoreUnit' 无效。

应该是
UPDATE GoodsSort SET [ScoreUnit]=100
这行出错,可是之前明明用IF EXISTS做了判断,ScoreUnit存在才执行UPDATE的。

怎样才能除掉这个错误?

经测试可以在ADD之后加GO指令,但这样相当于提交了上面的修改,即使后面的UPDATE出错,也不能一起ROLLBACK了。
SQL? 事务? 列? UPDATE

------解决方案--------------------
事务嵌套
begin tran t2
ALTER TABLE GoodsSort ADD ScoreUnit smallint DEFAULT (0) -- 如果ScoreUnit字段不存在则创建
commit tran t2
------解决方案--------------------
拆分成2个事务,如果第2个事务update出错,则删除字段ScoreUnit.

set xact_abort on
go

begin tran
 IF NOT EXISTS(SELECT * FROM syscolumns WHERE id=object_id('GoodsSort') and name='ScoreUnit')
 BEGIN
   PRINT '正在创建GoodsSort表的ScoreUnit字段;'
   ALTER TABLE GoodsSort ADD ScoreUnit smallint constraint DF_ScoreUnit DEFAULT (0) -- 如果ScoreUnit字段不存在则创建 
 END
commit tran
go

begin tran
 IF EXISTS(SELECT * FROM syscolumns WHERE id=object_id('GoodsSort') and name='ScoreUnit')
 BEGIN
   PRINT '正在更新GoodsSort表的ScoreUnit字段;'
   UPDATE GoodsSort SET [ScoreUnit]=100 --各类商品皆为100元积1分
 END
 
 If @@Error<>0
 begin
   PRINT '事务处理失败,回滚事务!'
   ALTER TABLE GoodsSort drop constraint DF_ScoreUnit
   ALTER TABLE GoodsSort drop column ScoreUnit
   rollback tran
 end
 else
 begin
   PRINT '事务处理成功,提交事务!'
   commit tran
 end

------解决方案--------------------
update 语句用exec('update ..........')
------解决方案--------------------