SET XACT_ABORT各种用法及显示结果

本文介绍了在数据库管理中如何使用SET XACT_ABORT命令,通过三个具体示例展示了该设置如何影响事务处理。在不同的用法下,它会决定事务在遇到错误时是仅回滚错误行还是全部回滚。此外,还探讨了插入语句与事务的关系,特别是在外键控制下的行为差异。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、准备工作:

       1、首先我们创建测试数据库:

create database demo

    2、创建数据表和测试数据:(这里注意外键控制)

use demo
CREATE TABLE student
(    
        stuid 
int NOT NULL PRIMARY KEY,
        stuname 
varchar(50)
)
CREATE TABLE score 
(
        stuid 
int NOT NULL REFERENCES student(stuid),
        score 
int
)
GO

INSERT INTO student VALUES (101,'zhangsan'
INSERT INTO student VALUES (102,'wangwu'
INSERT INTO student VALUES (103,'lishi'
INSERT INTO student VALUES (104,'maliu'

GO

二、各种用法及输出结果:

      1、语句1:

use demo

--Invoking a run-time error
SET XACT_ABORT OFF
BEGIN TRAN
    
INSERT INTO score  VALUES (101,90)
    
INSERT INTO score VALUES (102,78
    
INSERT INTO score VALUES (107,76/* Foreign Key Error */ 
    
INSERT INTO score VALUES (103,81
    
INSERT INTO score VALUES (104,65
COMMIT TRAN
go

      结果1:只回滚错误行,语句还继续执行。

--select * from score
101    90
102    78
103    81
104    65

 

      2、语句2:

use demo

--事务回滚
SET XACT_ABORT on
BEGIN TRAN
    
INSERT INTO score  VALUES (101,90)
    
INSERT INTO score VALUES (102,78
    
INSERT INTO score VALUES (107,76/* Foreign Key Error */ 
    
INSERT INTO score VALUES (103,81
    
INSERT INTO score VALUES (104,65
COMMIT TRAN
go

      结果2:事务终止并全部回滚,结果为空。

--select * from score

      3、语句3:

use demo

--事务在错误行终止,错误行回滚,错误行之前的不回滚
SET XACT_ABORT on
BEGIN
INSERT INTO score  VALUES (101,90)
    
INSERT INTO score VALUES (102,78
    
INSERT INTO score VALUES (107,76/* Foreign Key Error */ 
    
INSERT INTO score VALUES (103,81
    
INSERT INTO score VALUES (104,65
END
go

      结果3:出现这种是因为系统把每个insert语句都看成是单独的事务,所以错误行以前的是不回滚的。

--select * from score
101    90
102    78
USE [DXQcontrol_L1HIMCP1_Operational_W] GO /****** Object: StoredProcedure [dbo].[prodExecmgmtIdent__processBR] Script Date: 7/29/2025 9:03:21 AM ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO /*----------------------------------------------------------------------- Project: Duerr EcoEmos - Module Ident Stored Procedure: dbo.prodExecmgmtIdent__processBR Author: JM Initial date: 11. Nov 2020 Revisions: rev 1 - 11. Nov 2020, JM: wrapper function for the old OrderManagement to call dbo.prodExecmgmtIdent__processDR Input: @arg_dateEvt PLC timestamp of the reading event @arg_szRWStationTag Tagname for the reader (configured in table DS_CfgRegistrationPoint_TAB and for FB369 in addition in file IdentServer.ini) @arg_szDatasetIn Tracking data from PLC Output: @arg_szDatasetOut The mds data string which was merged by the new data from PLC and the last stored data string from DS_MDS_TAB Return: See the return codes of the several variables with name @iRetCode... ------------------------------------------------------------------------*/ CREATE PROCEDURE [dbo].[prodExecmgmtIdent__processBR] @arg_dateEvt DATETIME ,@arg_szRWStationTag NStringMin ,@arg_szDatasetIn VARCHAR(MAX) ,@arg_szDatasetOut VARCHAR(MAX) OUTPUT AS BEGIN SET NOCOUNT ON; SET XACT_ABORT ON; SET DEADLOCK_PRIORITY HIGH; DECLARE @object_name VARCHAR(128) = OBJECT_SCHEMA_NAME(@@PROCID) + '.' + OBJECT_NAME(@@PROCID); ---------------------------------------------------------------------------------------------------- -- PRREQ-1908: avoid start of process with an open or uncommitted transaction DECLARE @log VARCHAR(MAX) = ''; DECLARE @tempTable TABLE(logExt VARCHAR(MAX)); IF XACT_STATE() <> 0 BEGIN SET @log = 'Start ' + @object_name + '; '; SET @log += '@@TRANCOUNT = ' + CAST(@@TRANCOUNT AS VARCHAR(MAX)) + '; '; SET @log += 'XACT_STATE() = ' + CAST(XACT_STATE() AS VARCHAR(MAX)) + '; '; SET @log += '@@spid = ' + CAST(@@spid AS VARCHAR(MAX)) + '; '; SET @log += 'ProcParam: '; SET @log += 'rwStation: ' + @arg_szRWStationTag + '; '; SET @log += 'bodyId: ' + dbo.DS_FCT_GetPLCValueOf_(@arg_szDatasetIn, 'bodyId') + '; '; SET @log += 'skidId: ' + dbo.DS_FCT_GetPLCValueOf_(@arg_szDatasetIn, 'skidId') + '; '; SET @log += 'skidType: ' + dbo.DS_FCT_GetPLCValueOf_(@arg_szDatasetIn, 'skidType') + '; '; INSERT INTO @tempTable (logExt) SELECT DISTINCT 'spid=' + CAST(S.spid AS VARCHAR(MAX)) + '; hostname=' + RTRIM(S.hostname) + '; program_name=' + RTRIM(S.program_name) + '; hostprocess=' + RTRIM(S.hostprocess) + '; text=' + D.text + '; lastwaittype=' + RTRIM(S.lastwaittype) FROM sys.sysprocesses S CROSS APPLY sys.dm_exec_sql_text(S.sql_handle) D WHERE S.open_tran > 0; --ORDER BY S.hostname, S.program_name; ROLLBACK TRANSACTION; INSERT INTO dbo.DS_MDSErrorLog_TAB (dateEvt, rwStationId, source, errorCode, errorText) SELECT GETDATE(), @arg_szRWStationTag, @object_name, 'WARNING', isnull(logExt,'-') FROM @tempTable; EXEC dbo.DS_SP_MDSWriteToErrorLog @arg_rwStationId = @arg_szRWStationTag, @arg_szSource = @object_name, @arg_szErrorCode = 'WARNING', @arg_szErrorText = @log; END; ---------------------------------------------------------------------------------------------------- DECLARE @iRetValue INT; ------------------------------------------------------------------------------- -- write this information into log EXEC [dbo].[DS_SP_MDSWriteToLogger] @arg_szRWStationTag, @object_name, @arg_szDatasetIn; ------------------------------------------------------------------------------- -- set the prober function code SET @arg_szDatasetIn = STUFF( @arg_szDatasetIn, 1, 2, 'DR'); EXEC @iRetValue = [dbo].[prodExecmgmtIdent__processDR] @arg_dateEvt, -- DATETIME @arg_szRWStationTag, -- NStringMin @arg_szDatasetIn, -- VARCHAR(MAX) @arg_szDatasetOut OUTPUT; -- VARCHAR(MAX) RETURN @iRetValue; END; GO 逐条解析sqlserver的Sql语句语法用法
最新发布
07-30
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值