SET ARITHABORT (Transact-SQL)
适用于: SQL Server Azure SQL 数据库 Azure SQL 托管实例 Azure Synapse Analytics 分析平台系统 (PDW) Microsoft Fabric 中的 SQL 分析端点 Microsoft Fabric 中的仓库
在查询执行过程中发生溢出或被零除错误时结束查询。
语法
SQL Server、Azure Synapse Analytics 中的无服务器 SQL 池和 Microsoft Fabric 的语法
SET ARITHABORT { ON | OFF }
Azure Synapse Analytics 和 Analytics Platform System (PDW) 的语法
SET ARITHABORT ON
注解
在登录会话中始终将 ARITHABORT 设置为 ON。 将 ARITHABORT 设置为 OFF 可能对查询优化产生负面影响,进而导致性能问题。
警告
SQL Server Management Studio 的默认 ARITHABORT 设置为 ON。 客户端应用程序将 ARITHABORT 设置为 OFF 可以接收不同的查询计划,这使得对性能较差的查询进行故障排除变得困难。 也就是说,同一个查询可以在 Management Studio 中快速执行,但在应用程序中却比较慢。 使用 Management Studio 排除查询故障时,请始终与客户端 ARITHABORT 设置匹配。
如果 SET ARITHABORT 和 SET ANSI WARNINGS 均为 ON,则这些错误情况将导致查询结束。
如果 SET ARITHABORT 为 ON,但 SET ANSI WARNINGS 为 OFF,则这些错误情况将导致批处理结束。 如果在事务内发生错误,则回滚事务。 当 SET ARITHABORT 为 OFF 并发生这些错误之一时,将显示一条警告消息,并且算术运算的结果为 NULL
。
如果 SET ARITHABORT 和 SET ANSI WARNINGS 为 OFF,则会出现一条警告消息,并且算术运算的结果为 NULL
。
注意
如果 SET ARITHABORT 和 SET ARITHIGNORE 都不为 ON,SQL Server 将 NULL
返回并在查询运行后显示警告消息。
当 ANSI_WARNINGS 的值为 ON 且数据库兼容性级别设置为 90 或更高时,无论其值如何设置,ARITHABORT 都将隐式设置为 ON。 如果数据库兼容级别设置为 80 或更低,则必须将 ARITHABORT 选项显式设置为 ON。
对于表达式计算,如果 SET ARITHABORT 为 OFF,并且 INSERT、UPDATE 或 DELETE 语句遇到算术、溢出、除零或域错误,SQL Server 将插入或更新值 NULL
。 如果目标列不可为空,则插入或更新操作将失败,用户将看到错误消息。
如果 SET ARITHABORT 或 SET ARITHIGNORE 为 OFF,而 SET ANSI_WARNINGS 为 ON,则遇到被零除或溢出错误时,SQL Server 仍会返回错误消息。
如果 SET ARITHABORT 为 OFF,并且对 IF 语句的 Boolean 条件求值过程中发生中止错误,则执行 FALSE 分支。
在对计算列或索引视图创建或更改索引时,SET ARITHABORT 必须为 ON。 如果 SET ARITHABORT 为 OFF,则对包含计算列或索引视图索引的表执行 CREATE、UPDATE、INSERT 和 DELETE 语句时将失败。
SET ARITHABORT 的设置是在执行或运行时发生的,而不是在分析时发生的。
Azure Synapse Analytics 专用 SQL 池不支持 SET ARITHABORT OFF。
要查看 SET ARITHABORT 的当前设置,请运行以下查询:
DECLARE @ARITHABORT VARCHAR(3) = 'OFF';
IF ( (64 & @@OPTIONS) = 64 ) SET @ARITHABORT = 'ON';
SELECT @ARITHABORT AS ARITHABORT;
权限
要求 公共 角色具有成员身份。
示例
下例说明了在 SET ARITHABORT
设置下的被零除错误和溢出错误。
-- SET ARITHABORT
-------------------------------------------------------------------------------
-- Create tables t1 and t2 and insert data values.
CREATE TABLE t1 (
a TINYINT,
b TINYINT
);
CREATE TABLE t2 (
a TINYINT
);
GO
INSERT INTO t1
VALUES (1, 0);
INSERT INTO t1
VALUES (255, 1);
GO
PRINT '*** SET ARITHABORT ON';
GO
-- SET ARITHABORT ON and testing.
SET ARITHABORT ON;
GO
PRINT '*** Testing divide by zero during SELECT';
GO
SELECT a / b AS ab
FROM t1;
GO
PRINT '*** Testing divide by zero during INSERT';
GO
INSERT INTO t2
SELECT a / b AS ab
FROM t1;
GO
PRINT '*** Testing tinyint overflow';
GO
INSERT INTO t2
SELECT a + b AS ab
FROM t1;
GO
PRINT '*** Resulting data - should be no data';
GO
SELECT *
FROM t2;
GO
-- Truncate table t2.
TRUNCATE TABLE t2;
GO
-- SET ARITHABORT OFF and testing.
PRINT '*** SET ARITHABORT OFF';
GO
SET ARITHABORT OFF;
GO
-- This works properly.
PRINT '*** Testing divide by zero during SELECT';
GO
SELECT a / b AS ab
FROM t1;
GO
-- This works as if SET ARITHABORT was ON.
PRINT '*** Testing divide by zero during INSERT';
GO
INSERT INTO t2
SELECT a / b AS ab
FROM t1;
GO
PRINT '*** Testing tinyint overflow';
GO
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.
DROP TABLE t1;
DROP TABLE t2;
GO