SET ARITHABORT (Transact-SQL)

在查询执行过程中发生溢出或被零除错误时终止查询。

适用范围:SQL Server(SQL Server 2008 至当前版本),Windows Azure SQL Database(初始版本至当前版本)。

主题链接图标 Transact-SQL 语法约定

语法

SET ARITHABORT { ON | OFF }
[ ; ]

注释

在登录会话中,应始终将 ARITHABORT 设置为 ON。 将 ARITHABORT 设置为 OFF 可能对查询优化产生负面影响,进而导致性能问题。

备注

SQL Server Management Studio 的默认 ARITHABORT 设置为 ON。客户端应用程序将 ARITHABORT 设置为 OFF 可以接收不同的查询计划,使得对性能较差的查询进行故障排除变得困难。即,同一个查询可以在 Management Studio 中快速执行,但在应用程序中却比较慢。使用 Management Studio 排除查询故障时始终与客户端 ARITHABORT 设置匹配。

如果 SET ARITHABORT 为 ON,并且 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 都没有设置,则 SQL Server 将在执行查询后返回 NULL 和一条警告消息。

当数据库兼容级别设置为 90 或更高时,如果将 ANSI_WARNINGS 设置为 ON,则将使 ARITHABORT 隐式设置为 ON。 如果数据库兼容级别设置为 80 或更低,则必须将 ARITHABORT 选项显式设置为 ON。

如果 SET ARITHABORT 为 OFF,并且在对表达式求值的过程中 INSERT、DELETE 或 UPDATE 语句遇到算术错误(溢出、被零除或域错误),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 的设置是在执行或运行时设置的,而不是在分析时设置的。

要查看此设置的当前设置,请运行以下查询。

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

权限

要求具有 public 角色成员资格。

示例

下例说明了在两种 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

请参阅

参考

SET 语句 (Transact-SQL)

SET ARITHIGNORE (Transact-SQL)

SESSIONPROPERTY (Transact-SQL)