遇到了 “遇到以零作除數錯誤” 的問題


開發的時候,寫了個很簡單的Sql ,大概就是 總數除以數量 得出的平均值。看起來很平常是不是!簡單來說就是 Total / Count 嘛!最多轉個2位小數用Convert就完事了對不對。

但是呢,有些數據的Count值本身是就是0的。然后就會報遇到以0作為除數的錯誤的問題了啊~

然后演示幾種可能出現的情況,先初始化一個測試樣例,

 1 CREATE TABLE TmpA1 (ID INT IDENTITY(1,1),Total NUMERIC(8,2),CountNr INT)
 2 
 3 INSERT INTO dbo.TmpA1
 4         ( Total, CountNr )
 5 VALUES  ( 1,1 ),
 6         ( 1,1 ),
 7         ( 0,0 ),
 8         ( 1,1 ),
 9         ( 1,1 )
10 SELECT * FROM dbo.TmpA1
11 
12 ID          Total                                   CountNr
13 ----------- --------------------------------------- -----------
14 1           1.00                                    1
15 2           1.00                                    1
16 3           0.00                                    0
17 4           1.00                                    1
18 5           1.00                                    1
創建測試表

然后在一般默認的情況下如果使用這個語句,立馬就會粗線以下的錯誤。因為ID = 3 的數據里面除數為0嘛對不對

SELECT Total/CountNr FROM dbo.TmpA1

消息 8134,級別 16,狀態 1,第 10 行
遇到以零作除數錯誤。

但是如果是在查詢的時候沒有遇到這樣的數據,那當然就不會報錯羅 ~,比方說

SELECT Total/CountNr FROM dbo.TmpA1 WHERE ID <> 3

就正常了~

當然我們是不太可能在查詢的時候總是能跳過那些除數為0的數據的。有些也是要查出來。這樣的話。修改的方法還是多種,最常見的是這種直接處理

SELECT Total/CASE CountNr WHEN 0 THEN 1 ELSE CountNr END FROM dbo.TmpA1
SELECT CASE CountNr WHEN 0 THEN 0 ELSE Total/CountNr END FROM dbo.TmpA1

當然還是有另外的處理方法,就是屏蔽了“遇到以零作除數錯誤” 的錯誤信息(好拗口),這樣的話,遇到0是除數的情況,就是賦值為Null

SET ANSI_WARNINGS OFF;
SET ARITHIGNORE ON;
SET ARITHABORT OFF;
GO

SELECT 1 / 0
SELECT Total/CountNr FROM dbo.TmpA1

-----------
NULL

(1 行受影響)


---------------------------------------
1.0000000000000
1.0000000000000
NULL
1.0000000000000
1.0000000000000

可以說~這樣不是更加方便嗎?連Case when 都不用寫了!!最多處理一下Isnull,0 就好了嘛~但是!!!有幾種情況是不可以的

1 當我們有使用鏈接服務器的時候!比方說這樣紙,我隨便調用了我的另外一台服務器,因為 ANSI_WARNINGS 的選項保持一致的,so 就報錯啦!

SET ANSI_WARNINGS OFF;
SET ARITHIGNORE ON;
SET ARITHABORT OFF;
GO
SELECT *
    FROM [GINPC\GIN_Test].TestDB.dbo.TestTR1

消息 7405,級別 16,狀態 1,第 33 行
異類查詢要求為連接設置 ANSI_NULLS 和 ANSI_WARNINGS 選項。這將確保查詢語義一致。請啟用這些選項,然后重新發出查詢。

2 當使用xml的時候也會跪,比方說

SET ANSI_WARNINGS OFF;
SET ARITHIGNORE ON;
SET ARITHABORT OFF;
GO

DECLARE @Xml XML='
<R><I>3</I></R>
'

SELECT Total/CountNr 
    FROM dbo.TmpA1 a
        WHERE @Xml.exist('R/I[text()=sql:column("a.ID")]') = 1

當涉及到xml作為參數的時候,就會提示到這個ANSI_WARNING 這個設置不正確。這個原理我就不是太懂,還希望各位指教。

但是解決方法也是比較簡單的。就是把查詢脫離xml解析的作用域就可以了。這個倒是好解決

 

嗯~這次也說道這里~請各位清拍

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM