如何在Sybase ASE中处理事务?

时间:2014-08-01 18:35:21

标签: error-handling transactions sybase sybase-ase

我必须将记录插入测试环境中的表中,以便我现在知道它将抛出主键约束违规。而且由于脚本在从环境迁移到另一个环境时将由其他人独立运行,我希望在遇到问题时让我的脚本回滚。

我的脚本如下:

use my_db
go

--
-- No rows of the given "my_code" must exist, as they shall be replaced.
--
if exists (
        select 1
            from my_table
            where my_code like 'my_code'
) delete from my_table
    where my_code like 'my_code'

--
-- All rows shall be inserted altogether, or rejected altogether at once.
--
begin tran a
    insert into my_table (field1, field2, field3) values (value1, value2, value3)

    if @@error != 0 or @@transtate != 0
        begin
            rollback tran a
        end

    insert into my_table (field1, field2, field3) values (value1, value2, value3)

    if @@error != 0 or @@transtate != 0
        begin
            rollback tran a
        end

    commit tran a
go

我已经尝试过从这些帖子中得到的信息:

我试过只验证@@error@@transtate和两者,并且我总是得到报告错误的消息框,并且没有回滚记录,也就是说,仍然插入了传递的行

我想知道是否有办法确保Sybase按预期充分处理事务,或者只是确保它在SQL Server允许时插入行时不自动提交行 - 我的意思是,SQL Server继承毕竟,从Sybase开始......它是Sybase的新手,还是SQL Server的新手,我不知道。

我希望避免出现错误,最好记录错误并回滚或删除事务中插入的行。

请注意,我不使用存储过程。此脚本是一次性更新数据库,以查找使用该数据库的软件中发生的最近更改。

1 个答案:

答案 0 :(得分:2)

代码看起来大致正确。如果在插入时遇到重复键错误,那么这将被IF测试捕获。

但是,您还应该添加一些基于标志的逻辑(GOTO或其他IF-ELSE测试),当您决定回滚第一个插入时,它会跳过第二个插入。

目前,您的代码将始终执行第二次插入,无论如何。与其他一些数据库不同,在 ASE控制流不受错误条件影响,您需要自己拦截

另请注意,两个插入都是相同的,因此如果表上有唯一索引,则第二个插入将始终生成重复键错误,如果第一个插入成功。

听起来好像您正在使用客户端在每个语句之后检查状态? ASE本身不会弹出任何错误消息框。

要开发它,最好使用

从命令行运行脚本
isql [...] -i yourscriptfile.sql

只有两个评论:

  • 您正在使用交易名称('a')。这不是必需的,实际上可能会导致问题:当您回滚到命名事务时,必须是最外层事务,否则回滚将失败。最好不要使用交易名称。
  • 如果在执行此代码时已经激活了事务,则实际上会发生上一个项目符号中的此问题。您应该始终使用

    在脚本的开头进行检查

    if @@ trancount> 0     开始         print'错误:事务已处于活动状态'         返回     结束

或类似的东西。

HTH,

Rob V。