SET ARITHABORT (Transact-SQL)
在查询执行过程中发生溢出或被零除错误时终止查询。
适用范围:SQL Server(SQL Server 2008 至当前版本),Windows Azure SQL Database(初始版本至当前版本)。 |
语法
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