很多场景中,我们使用触发器来回滚一些不满足业务逻辑的修改,这没有问题,问题是我能在触发器中提交事务吗?

这个问题很小白,当也来测试一下

/*
测试中创建三种表,对表 TB2 插入时触发触发器,
在触发器中将TB2中新插入的数据插入到 TB3 和 TB4
*/
USE TestDB
GO 
DROP TABLE TB2
GO
DROP TABLE TB3
GO
DROP TABLE TB4
GO
CREATE TABLE TB2
(
 ID INT PRIMARY KEY IDENTITY,
 C1 INT
)
GO
CREATE TABLE TB3
(
 ID INT PRIMARY KEY,
 C1 INT
)
GO
CREATE TABLE TB4
(
 ID INT PRIMARY KEY,
 C1 INT
)
GO
--=======================================
--创建触发器
CREATE TRIGGER utr_TB2_INSERT
   ON  dbo.TB2
   AFTER INSERT
AS
BEGIN
 SET NOCOUNT ON;

INSERT INTO dbo.TB3(ID,C1)
    SELECT ID,C1 FROM inserted
   
    COMMIT
   
    INSERT INTO dbo.TB4(ID,C1)
    SELECT ID,C1 FROM inserted

END
GO

--====================================
--在事务中尝试插入数据
BEGIN TRAN TR1
INSERT INTO TB2(ID,C1)
SELECT 1,1
SELECT @@TRANCOUNT
COMMIT

--====================================
--错误提示
/*
Msg 544, Level 16, State 1, Line 4
Cannot insert explicit value for identity column in table 'TB2' when IDENTITY_INSERT is set to OFF.
*/
--====================================

--====================================
--在非事务中尝试插入数据
INSERT INTO TB2(ID,C1)
SELECT 1

--====================================
--错误提示
/*
Msg 120, Level 15, State 1, Line 3
The select list for the INSERT statement contains fewer items than the insert list.
The number of SELECT values must match the number of INSERT columns.
*/
--====================================

测试结论:
虽然可以创建出包含COMMIT语句的触发器,但是不应该在触发器中提交事务。

扩充:
如果不希望触发器中操作异常引发外部回滚,是否可以使用事务点来实现
--=======================================
--创建触发器
DROP TRIGGER [dbo].[utr_TB2_INSERT]
GO
CREATE TRIGGER utr_TB2_INSERT
   ON  dbo.TB2
   AFTER INSERT
AS
BEGIN
 SET NOCOUNT ON;
    SAVE TRANSACTION TR1;
    BEGIN TRY
    INSERT INTO dbo.TB3(ID,C1)
    SELECT ID,C1 FROM inserted

INSERT INTO dbo.TB4(ID,C1)
    SELECT ID,C1 FROM inserted
    END TRY
    BEGIN CATCH
    ROLLBACK TRANSACTION TR1
 END CATCH
END
GO
--=======================================
--答案:不可以

/*
Msg 3931, Level 16, State 1, Procedure utr_TB2_INSERT, Line 17
The current transaction cannot be committed and cannot be rolled back to a savepoint.
 Roll back the entire transaction.
*/

TSQL--可以在触发器中使用COMMIT吗?的更多相关文章

  1. oracle 中触发器增加存储过程commit问题

    触发器无需commit也不能写commit触发器和触发它的DML是同一个事务DML提交了,触发器的操作也提交了,要不就一起回滚了 当然,如果你一定要在触发器里写COMMIT那就用自治事务相当于一个事务 ...

  2. ORA-04092: COMMIT 不能在触发器中

    触发器无需commit也不能写commit触发器和触发它的DML是同一个事务DML提交了,触发器的操作也提交了,要不就一起回滚了 当然,如果你一定要在触发器里写COMMIT那就用自治事务相当于一个事务 ...

  3. 如何在Oracle触发器中使用查询语句

    通常情况下,Oracle数据库禁止在行级触发器或行级触发器所调用的子程序中使用查询语句.但是,面对复杂的业务逻辑,不可避免的要使用查询语句. 当在行级触发器中使用查询语句时,Oracle数据库会抛出O ...

  4. Oracle中的commit详解

    本文转自 : http://blog.csdn.net/hzhsan/article/details/9719307 它执行的时候,你不会有什么感觉.commit在数据库编程的时候很常用,当你执行DM ...

  5. SQL触发器中的deleted表和inserted表

    SQL触发器中的deleted表和inserted表 在触发器语句中用两个特殊的表一个是deleted表和inserted.它们是通过触发器操作自动创建驻留在内存中的临时表. 描述: Deleted表 ...

  6. 使用t-sql从身份证号中提取生日

    使用t-sql从身份证号中提取生日,一下是转换16位身份证号的例子,仅供参考. create function getDateFromID( ) ) returns datetime as begin ...

  7. oracle触发器中增删改查本表

    oracle触发器中增删改查本表 (1)只有before insert触发器中才可以查询或更新本表 create or replace trigger tri_test_ins before inse ...

  8. 触发器中的inserted表和deleted表

    触发器语句中使用了两种特殊的表:deleted 表和 inserted 表.Microsoft? SQL Server 2000 自动创建和管理这些表.可以使用这两个临时的驻留内存的表测试某些数据修改 ...

  9. SQL server触发器中 update insert delete 分别给写个例子被。

    SQL server触发器中 update insert delete 分别给写个例子以及解释下例子的作用和意思被, 万分感谢!!!! 主要想知道下各个语句的书写规范. INSERT: 表1 (ID, ...

随机推荐

  1. (halcon) derivate_vector_field

    derivate_vector_field: Convolve a vector field with derivatives of the Gaussian 用高斯导数卷积向量场 derivate_ ...

  2. python:窗口化和制作图形

    #圆 from tkinter import * canvas = Canvas(width=800, height=600, bg='yellow')#声明窗口属性 canvas.pack(expa ...

  3. Keepalive VIP 故障

    前端环境如下: Nginx + Keepalived ( MASTER ) --> node * | | Cisco ASA --> VIP 1.18 | | Nginx + Keepal ...

  4. 从邮件原理来看 postfix和docecot

    好早好早以前计算机网络老师就教了说,邮件嘛,就三个协议smtp,imap,pop3. smtp 用来发邮件,imap,pop3用来收邮件.噢?是么.难道没有发现这句话有非常多的漏洞,根本就不能说清楚这 ...

  5. WPF——Sharder实现Logo走光动画

    利用WPF的走光动画实现的走光动画. 资源  实例程序 示例代码 LogoEffect logoEffect = }; //要添加走光动画的物体 logo.Effect = logoEffect; D ...

  6. Java CST格式字符串转换成Date类型的数据

    Date date = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", Locale.US).parse("We ...

  7. Creating Procedural Textures

    [Creating Procedural Textures] 由程序主生贴图,然后设置给Material.首先定义需要的数据: 在Start方法中完成初始化,注意设置的是_MainTex. 实现Gen ...

  8. 【codeforces 1025E】Colored Cubes 【构造】

    题意 有一个n*n的棋盘和m个棋子,每个棋子有一个初始位置和一个目标位置,每次移动只能选择一个棋子移动到他相邻的格子,并且花费一秒钟.请你找出一个移动的方法,使得在10800步内将所有棋子移动到目标位 ...

  9. Leetcode catalogue

    1. Array & List 1.1Sort Array的变更操作,好好运用尾指针:88题的end,75题的blueHead 88. Merge Sorted Array (Array) 7 ...

  10. Ubuntu设置屏幕分辨率

    Ubuntu设置屏幕分辨率 原创 2016年10月14日 13:01:24 14900 在虚拟机装好Ubuntu,进入系统分辨率是800*600,打开显示界面设置下分辨率,设置完怎么也选不上应用,于是 ...