SET SET ARITHABORT (Transact-SQL)

适用于:SQL ServerAzure SQL 数据库Azure SQL 托管实例Azure Synapse Analytics分析平台系统(PDW)Microsoft Fabric 中的 SQL 分析终结点Microsoft Fabric 中的仓库Microsoft Fabric 中的 SQL 数据库

SET ARITHABORT 设置决定了在查询执行过程中发生溢出或除以零错误时,查询是否会停止。

  • 当你设置 SET ARITHABORT ONSET ANSI_WARNINGS OFF时,算术错误会导致批次结束。 如果在事务内发生错误,则回滚事务。

  • 如果 和 都是且发生算术错误,则会出现警告消息(除非 SET ARITHIGNOREON),算术运算的结果为 NULLOFFSET ANSI_WARNINGSSET ARITHABORT

Transact-SQL 语法约定

语法

SQL Server 语法,Azure Synapse Analytics 中的 serverless SQL 池,Microsoft Fabric 中的 SQL 数据库,Microsoft Fabric 中的 SQL 数据库


SET ARITHABORT { ON | OFF }

Azure Synapse Analytics 和 Analytics Platform System (PDW) 的语法


SET ARITHABORT ON

注解

当 是ON(默认值)时ANSI_WARNINGS,设置 没有ARITHABORT功能性影响。 算术错误会导致查询结束,但批处理不会中止(只要设置 XACT_ABORTOFF)。

警告

SQL Server Management Studio(SSMS)的默认ARITHABORT设置是 ON,而应用程序中的客户端连接默认为 ARITHABORT OFF。 即使功能上没有差别,只要 ANSI_WARNINGSON设置 ARITHABORT 仍然是缓存密钥。 因此,SSMS 和应用程序各自使用默认设置,缓存条目不同,查询计划也可能不同,导致排查性能不佳的查询变得困难。 也就是说,同一个查询在应用中的执行速度可能比在 SSMS 中慢。 在使用 Management Studio 排查查询时,务必与客户端 ARITHABORT 设置保持一致。

对于表达式的求值,如果两个 和 都是,且 INSERTUPDATEDELETE 语句遇到算术、溢出、除以零或域错误,查询将插入或更新一个NULL值。OFFSET ARITHABORTSET ANSI_WARNINGS 如果目标列不可为空,则插入或更新操作将失败,用户将看到错误消息。

SET ARITHABORT 设置发生在执行或运行时,而不是解析时。

SET ARITHABORT OFF在 Azure Synapse Analytics 专用 SQL 池中不支持 。

权限

要求 公共 角色具有成员身份。

查看当前设置 ARITHABORT

要查看当前 SET ARITHABORT的设置,请执行以下 T-SQL 查询:

DECLARE @ARITHABORT VARCHAR(3) = 'OFF';  
IF ( (64 & @@OPTIONS) = 64 ) SET @ARITHABORT = 'ON';  
SELECT @ARITHABORT AS ARITHABORT;  

示例

以下示例展示了不同 SET ARITHABORT 设置下的除以零和溢出误差。

  1. 脚本创建样本表 t1t2 插入样本数据值。
  2. 设置 ANSI_WARNINGS ON 并运行测试,以观察除以零误差和算术溢出的默认行为。
  3. ANSI_WARNINGS OFF为 有ARITHABORT效果,且 。ARITHABORT ON 运行测试,观察这种行为,出现除以零的误差和算术溢出。
  4. 设两者 ANSI_WARNINGS OFFARITHABORT OFF。 运行测试,观察这种行为,出现除以零的误差和算术溢出。
  5. 清理样品表。
-- SET ARITHABORT  
-------------------------------------------------------------------------------  
-- Create tables t1 and t2 and insert data values.  
CREATE TABLE t1 (  
   a TINYINT,   
   b TINYINT  
);  
CREATE TABLE t2 (  
   a TINYINT NOT NULL  
);  
GO  
INSERT INTO t1   
VALUES (1, 0);  
INSERT INTO t1   
VALUES (255, 1);  
GO  

-- First run with ANSI_WARNINGS ON to see the default behavior.
PRINT '*** SET ANSI_WARNINGS ON';  
SET ANSI_WARNINGS ON;
SET XACT_ABORT OFF;    -- To make sure that we have the default setting for this option.  
GO
PRINT '*** Testing divide-by-zero during SELECT';  
GO  
SELECT a / b AS ab   
FROM t1;  
PRINT 'This prints, despite the error message.';
GO  

PRINT '*** Testing divide-by-zero during INSERT';  
GO  
INSERT INTO t2  
SELECT a / b AS ab    
FROM t1;  
PRINT 'This prints, despite the error message.';
GO  

PRINT '*** Testing tinyint overflow';  
GO  
INSERT INTO t2  
SELECT a + b AS ab   
FROM t1;  
PRINT 'This prints, despite the error message.';
GO  

PRINT '*** Resulting data - should be no data';  
GO  
SELECT *   
FROM t2;  
GO  

-- Truncate table t2.  
TRUNCATE TABLE t2;  
GO  

-- Set ANSI_WARNINGS OFF so that ARITHABORT has effect, and set ARITHABORT ON.
PRINT '*** SET ANSI_WARNINGS OFF; SET ARITHABORT ON';  
GO  
SET ANSI_WARNINGS OFF; 
SET ARITHABORT ON;  
GO  

PRINT '*** Testing divide-by-zero during SELECT';  
GO  
SELECT a / b AS ab    
FROM t1;  
PRINT 'This does not print.';
GO  

PRINT '*** Testing divide-by-zero during INSERT';  
GO  
INSERT INTO t2  
SELECT a / b AS ab    
FROM t1;  
PRINT 'This does not print.';
GO  
PRINT '*** Testing tinyint overflow';  
GO  
INSERT INTO t2  
SELECT a + b AS ab   
FROM t1;  
PRINT 'This does not print.';
GO  

PRINT '*** Resulting data - should be 0 rows';  
GO  
SELECT *   
FROM t2;  
GO  

-- Truncate table t2.  
TRUNCATE TABLE t2;  
GO  

-- Set both ANSI_WARNINGS OFF and ARITHABORT OFF.
PRINT '*** SET ARITHABORT OFF';  
GO  
SET ARITHABORT OFF;  
GO  

PRINT '*** Testing divide-by-zero during SELECT';  
GO  
-- Returns NULL.
SELECT a / b AS ab    
FROM t1;  
GO  

PRINT '*** Testing divide-by-zero during INSERT';  
GO  
-- Fails with NOT NULL violation.
INSERT INTO t2  
SELECT a / b AS ab    
FROM t1;  
GO  
PRINT '*** Testing tinyint overflow';  
GO  
-- Fails with NOT NULL violation
INSERT INTO t2  
SELECT a + b AS ab   
FROM t1;  
GO  

PRINT '*** Resulting data - should be 0 rows';  
GO  
SELECT *   
FROM t2;  
GO  

-- Drop tables t1 and t2 and restore ANSI_WARNINGS
DROP TABLE t1;  
DROP TABLE t2;  
SET ANSI_WARNINGS ON
GO