zoukankan      html  css  js  c++  java
  • 触发器学习

    After 触发器将在处理触发操作(Insert、Update 或 Delete)、Instead Of 触发器和约束之后激发。Instead Of是将在处理约束前激发,以替代触发操作。

    After触发器在触发时操作已影响表中数据,Instead of 触发器触发时操作未影响数据表中数据。

    不存在DDL 类型的Instead of 触发器,在DDL触发器创建时可以使用Instead表和Deleted表,但是会引发运行时异常。

    可以在存储过程或触发器中执行 ROLLBACK TRANSACTION 或 COMMIT TRANSACTION Transact-SQL 语句,但这样可能会导致错误。(MSDN)

    应该在触发器中尽量避免事务会滚操作,测试如下:

    --创建测试环境
    USE tempdb
    GO
    CREATE TABLE dbo.TRTest
    (
    ID INT
    )
    GO
    CREATE TABLE dbo.TRTestHistory
    (
    ID INT,
    InsertDate datetime default GETDATE()
    );
    -- 创建INSTEAD OF 触发器
    --
    第一次向dbo.TRTestHistory插入数据,然后回滚事务
    --
    第二次向dbo.TRTestHistory插入数据,然后提交事务
    CREATE TRIGGER TR_TRTest ON dbo.TRTest
    INSTEAD OF INSERT
    AS
    BEGIN
    BEGIN TRAN
    Insert into dbo.TRTestHistory(ID)
    SELECT ID FROM inserted
    ROLLBACK TRAN

    BEGIN TRAN
    Insert into dbo.TRTestHistory(ID)
    SELECT ID+100 FROM inserted
    COMMIT TRAN
    END
    --清理表中数据
    TRUNCATE TABLE dbo.TRTest
    TRUNCATE TABLE dbo.TRTestHistory

    --尝试插入数据,触发TR_TRTest触发器
    INSERT INTO dbo.TRTest
    SELECT 1

    --检查数据表中数据
    SELECT * FROM dbo.TRTest
    SELECT * FROM dbo.TRTestHistory
    结果:插入操作提示错误“The transaction ended in the trigger. The batch has been aborted.”,但dbo.TRTestHistory表中有数据插入。
     
    -- 创建INSTEAD OF 触发器
    --
    第一次向dbo.TRTestHistory插入数据,然后回滚事务
    --
    第二次向dbo.TRTestHistory插入数据,然后提交事务
    ALTER TRIGGER TR_TRTest ON dbo.TRTest
    INSTEAD OF INSERT
    AS
    BEGIN
    BEGIN TRAN TR1
    Insert into dbo.TRTestHistory(ID)
    SELECT ID FROM inserted
    ROLLBACK TRAN TR2

    BEGIN TRAN
    Insert into dbo.TRTestHistory(ID)
    SELECT ID+100 FROM inserted
    COMMIT TRAN
    END
    --清理表中数据
    TRUNCATE TABLE dbo.TRTest
    TRUNCATE TABLE dbo.TRTestHistory

    --尝试插入数据,触发TR_TRTest触发器
    INSERT INTO dbo.TRTest
    SELECT 1

    --检查数据表中数据
    SELECT * FROM dbo.TRTest
    SELECT * FROM dbo.TRTestHistory
    结果:插入时异常“Cannot roll back TR1. No transaction or savepoint of that name was found. The statement has been terminated. ”,
    但dbo.TRTestHistory表中没有数据
    -- 创建AFTER触发器
    --
    第一次向dbo.TRTestHistory插入数据,然后回滚事务
    --
    第二次向dbo.TRTestHistory插入数据,然后提交事务
    ALTER TRIGGER TR_TRTest ON dbo.TRTest
    AFTER INSERT
    AS
    BEGIN
    BEGIN TRAN TR1
    Insert into dbo.TRTestHistory(ID)
    SELECT ID FROM inserted
    ROLLBACK TRAN TR1

    BEGIN TRAN
    Insert into dbo.TRTestHistory(ID)
    SELECT ID+100 FROM inserted
    COMMIT TRAN
    END
    --清理表中数据
    TRUNCATE TABLE dbo.TRTest
    TRUNCATE TABLE dbo.TRTestHistory

    --尝试插入数据,触发TR_TRTest触发器
    INSERT INTO dbo.TRTest
    SELECT 1

    --检查数据表中数据
    SELECT * FROM dbo.TRTest
    SELECT * FROM dbo.TRTestHistory
    结果:插入时异常“Cannot roll back TR1. No transaction or savepoint of that name was found. The statement has been terminated. ”,
    但dbo.TRTestHistory表中没有数据



    总结:大部分情况下在触发器中使用ROLLBACK TRAN会导致包括触发器内部以及引发触发器激活的操作在内的事务会滚,但部分情况下触发器ROLLBACK TRAN后续的操作仍能操作成功。

  • 相关阅读:
    select,radio,checkbox的美化
    BBMASTER 博客
    thymeleaf教程
    Spring Boot入门01
    thymeleaf
    [转]Eclipse中10个最有用的快捷键组合
    SpringMVC实现文件上传
    Maven_项目管理利器入门
    [转]centos6.5安装mysql
    YOUNG博客项目设计书_v01.00_账号管理模块
  • 原文地址:https://www.cnblogs.com/TeyGao/p/2333878.html
Copyright © 2011-2022 走看看