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 ARITHABORT 和 皆為SET ANSI_WARNINGS且發生算術錯誤,則會出現警告訊息(除非 OFFSET ARITHIGNORE),且算術運算結果為 ONNULL

Transact-SQL 語法慣例

Syntax

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

備註

ANSI_WARNINGSON 預設值時,設定 沒有 ARITHABORT 功能性影響。 算術錯誤會導致查詢結束,但只要設定 XACT_ABORTOFF,批次不會中止。 算術錯誤包括溢位錯誤、除以零錯誤或範疇錯誤。

警告

SQL Server Management Studio(SSMS)的預設ARITHABORT設定為 ON,而應用程式中的用戶端連線預設為 ARITHABORT OFF。 即使功能上沒有差異,只要 ANSI_WARNINGSON設定 ARITHABORT 仍然是快取金鑰。 因此,SSMS 與應用程式各自使用預設值時,快取項目不同,查詢計畫也可能不同,導致難以排除執行不佳的查詢。 也就是說,同一個查詢在應用程式中的執行速度可能比 SSMS 慢。 在用 Management Studio 排除問題時,務必與客戶端 ARITHABORT 設定相符。

對於表達式評估,若兩個 SET ANSI_WARNINGSSET ARITHABORT 都是INSERTOFF且 、 、 UPDATEDELETE 陳述句遇到算術錯誤,查詢會插入或更新一個NULL值。 如果目標資料行不可為 Null,插入或更新動作就會失敗,而使用者會看見錯誤。

SET ARITHABORT 設定發生在執行或執行時,而非解析時。

SET ARITHABORT OFF在 Azure Synapse Analytics 專用的 SQL 池中不支援。

權限

需要 public 角色的成員資格。

查看目前的設定 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