Sql-Server
為什麼“SELECT POWER(10.0, 38.0);”拋出算術溢出錯誤?
我正在更新我的
IDENTITY
溢出檢查腳本以說明DECIMAL
和NUMERIC
IDENTITY
列。作為檢查的一部分,我計算每一
IDENTITY
列的數據類型範圍的大小;我用它來計算該範圍的百分比已用盡。對於該範圍的大小,DECIMAL
精度在哪裡。NUMERIC
2 * 10^p - 2
p
我創建了一堆帶有
DECIMAL
和NUMERIC
IDENTITY
列的測試表,並嘗試按如下方式計算它們的範圍:SELECT POWER(10.0, precision) FROM sys.columns WHERE is_identity = 1 AND type_is_decimal_or_numeric ;
這引發了以下錯誤:
Msg 8115, Level 16, State 6, Line 1 Arithmetic overflow error converting float to data type numeric.
我將它縮小到
IDENTITY
類型的列DECIMAL(38, 0)
(即具有最大精度),所以我然後POWER()
直接嘗試對該值進行計算。以下所有查詢
SELECT POWER(10.0, 38.0); SELECT CONVERT(FLOAT, (POWER(10.0, 38.0))); SELECT CAST(POWER(10.0, 38.0) AS FLOAT);
也導致了同樣的錯誤。
- 為什麼 SQL Server 會嘗試將
POWER()
類型為 的輸出轉換FLOAT
為NUMERIC
(尤其是在FLOAT
具有更高優先級時)?- 如何為所有可能的精度(當然包括)動態計算 a
DECIMAL
或列的範圍?NUMERIC``p = 38
從
POWER
文件中:句法
POWER ( float_expression , y )
論據
float_expression
是float類型或可以隱式轉換為float的類型的表達式。
y
是提高float_expression的冪。*y可以是精確數值或近似數值數據類型類別的表達式,*位數據類型除外。
返回類型
返回與float_expression中送出的類型相同的類型。例如,如果將小數(2,0) 作為 float_expression 送出,則返回的結果為小數(2,0)。
float
如有必要,第一個輸入將被隱式轉換為。
float
內部計算由標準 C 執行時庫 (CRT) 函式使用算術執行pow
。然後將
float
輸出pow
轉換回左側操作數的類型(暗示numeric(3,1)
當您使用文字值 10.0 時)。在您的情況下使用顯式
float
工作正常:SELECT POWER(1e1, 38); SELECT POWER(CAST(10 as float), 38.0);
10 38的精確結果不能儲存在 SQL Server 中
decimal/numeric
,因為它需要 39 位精度(1 後跟 38 個零)。最大精度為 38。