zoukankan      html  css  js  c++  java
  • tsql中的事务控制及错误处理

    ------------------------------------------------事务控制-----------------------------------------------------

    Sql Server 2005/2008中提供了begin tran,commit tran和rollback tran来使用事务。
    begin tran表示开始事务, commit tran表示提交事务,rollback tran表示回滚事务
    begin tran 可以理解成新建一个还原点;
    commit tran提交这个自begin tran开始的修改;
    rollback tran 表示还原到上个还原点。

    先创建工作表

    USE master
    CREATE TABLE student
    (
    stuid INT NOT NULL PRIMARY KEY,
    stuname VARCHAR(50)
    )
    CREATE TABLE score
    (
    stuid INT NOT NULL REFERENCES student(stuid),
    score INT
    )

    如下示例不太恰当, 但正确使用了事务 

    begin tran

    INSERT INTO student VALUES (101,'zhangsan')
    INSERT INTO student VALUES (102,'wangwu')

    INSERT INTO score VALUES (101,190)
    INSERT INTO score VALUES (102,78)

    if exists(select 1 from score where score>100)--如果有>100分的成绩,则回滚整个事务
    rollback
    else
    commit tran

    因为事务里有插入分数为190(>100)的记录, 所以整个事务回滚。

    ------------------------------------------------错误处理 Error Handling-----------------------------------------------------

    对于运行时错误或异常呢?

    先准备如下数据:

    INSERT INTO student VALUES (101,'zhangsan')
    INSERT INTO student VALUES (102,'wangwu')
    INSERT INTO student VALUES (103,'lishi')
    INSERT INTO student VALUES (104,'maliu')
    --调用一个运行时错误
    SET XACT_ABORT OFF
    BEGIN TRAN
    INSERT INTO score VALUES (101,90)
    INSERT INTO score VALUES (102,78)
    INSERT INTO score VALUES (107, 76) /* 外键错误 */
    INSERT INTO score VALUES (103,81)
    INSERT INTO score VALUES (104,65)
    COMMIT TRAN

    执行如上sql,出现了运行时错误(外键冲突), 整个事务无法回滚

    如果产生异常,则事务是不会回滚的, 此时要借助如下2种方法:

    1)SET XACT_ABORT ON
    SET XACT_ABORT ON时,在事务中,若出现错误,系统即默认回滚事务,但只对非自定义错误有效

    SET XACT_ABORT OFF,默认值,在事务中,回滚一个语句还是整个事务视错误的严重程序而定,用户级错误一般不会回滚整个事务
    When SET XACT_ABORT is ON, if a Transact-SQL statement raises a run-time error, the entire transaction is terminated and rolled back.
    The setting of SET XACT_ABORT is set at execute or run time and not at parse(从语法上分析;解析) time.

    SET XACT_ABORT ON
    BEGIN TRAN
    INSERT INTO score VALUES (101,90)
    INSERT INTO score VALUES (102,78)
    INSERT INTO score VALUES (107, 76) /* 外键错误 */
    INSERT INTO score VALUES (103,81)
    INSERT INTO score VALUES (104,65)
    COMMIT TRAN
    SET XACT_ABORT OFF

    执行后会抛出异常:

    消息 547,级别 16,状态 0,第 6 行
    INSERT 语句与 FOREIGN KEY 约束"FK__score__stuid__5C37ACAD"冲突。该冲突发生于数据库"master",表"dbo.student", column 'stuid'。

    2)使用TRY...CATCH构造,并调用一个运行时错误

    SET XACT_ABORT OFF
    BEGIN TRY
    BEGIN TRAN
    INSERT INTO score VALUES (101,90)
    INSERT INTO score VALUES (102,78)
    INSERT INTO score VALUES (107, 76) /* 外键错误 */
    INSERT INTO score VALUES (103,81)
    INSERT INTO score VALUES (104,65)
    COMMIT TRAN
    PRINT '事务提交'
    END TRY
    BEGIN CATCH
    ROLLBACK
    PRINT '事务回滚'
    SELECT ERROR_NUMBER() AS ErrorNumber,
    ERROR_SEVERITY() AS ErrorSeverity,
    ERROR_STATE() as ErrorState,
    ERROR_MESSAGE() as ErrorMessage;
    END CATCH

    此时,会print出“事务回滚”, 错误信息为:

    ErrorNumber ErrorSeverity ErrorState ErrorMessage
    547 16 0 INSERT 语句与 FOREIGN KEY 约束"FK__score__stuid__5C37ACAD"冲突。该冲突发生于数据库"master",表"dbo.student", column 'stuid'。

    当看到一些不好的代码时,会发现我还算优秀;当看到优秀的代码时,也才意识到持续学习的重要!--buguge
    本文来自博客园,转载请注明原文链接:https://www.cnblogs.com/buguge/archive/2012/03/08/2385477.html


  • 相关阅读:
    linux重新编译内核
    无废话ubuntu 13.4w文件共享配置
    VB6关于判断模态窗体的问题
    在.NET中快速创建一个5GB、10GB或更大的空文件
    利用虚拟光驱实现 将WINDOWS文件供虚拟机中的UBUNTU共享
    论这场云盘大战,以及各网盘的优劣
    struts2 全局格式化,格式化时间,金钱,数字
    SQL SERVER 2000/2005/2008数据库数据迁移到Oracle 10G细述
    女攻城师走在移动互联网道路的这两年
    用正则匹配多行文本
  • 原文地址:https://www.cnblogs.com/buguge/p/2385477.html
Copyright © 2011-2022 走看看