[英]Why does this SQL query fail
下面的查詢意外失敗,出現算術溢出錯誤。
select IsNull(t2.val, 5005)
from(
SELECT 336.6 as val UNION ALL
SELECT NULL
) as t2
“將int轉換為數據類型numeric的算術溢出錯誤。”
奇怪的是,如果修改查詢以刪除NULL並將其替換為與null coalesce(5005)中相同的值,則它會運行而沒有問題
select IsNull(t2.val, 5005)
from(
SELECT 336.6 as val UNION ALL
SELECT 5005
) as t2
另外,省略SELECT NULL行完全允許查詢無問題地運行
select IsNull(t2.val, 5005)
from(
SELECT 336.6 as val
) as t2
如果IsNull函數中的coalesce值更改為一個小於足以在子查詢中轉換為十進制而不加寬的整數,則查詢將運行
select IsNull(t2.val, 500)
from(
SELECT 336.6 as val UNION ALL
SELECT NULL
) as t2
在SQL Server 2005和SQL Server 2008中都進行了測試。
通常將整數與小數組合是無縫的,SQL Server會將整數和小數轉換為足以容納兩者的十進制類型。 但由於某種原因,運行查詢,其中從UNION和IsNull都發生轉換,導致轉換失敗。
有人知道為什么是這樣嗎?
試試這個
select * into t2
from(
SELECT 336.6 as val
UNION ALL
SELECT NULL
) as x
如果現在查看列,則會看到數字精度為4且比例為1的數字
select * from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME='T2'
SQL根據最小的數字精度做出決定,以保持336.6。 現在,當你要求它將NULL轉換為5005時,你要說的是,將任何NULL值轉換為一個太大而不適合數字的數字,精度為4,比例為1.錯誤信息表示5005韓元'適合數字(4,1)
這將起作用,因為該表現在將生成一個更大的數字字段,因為SQL需要容納5005.使用下面的T2的新內容創建表,字段類型應該轉到數字(5,1)允許5005到適合。
select IsNull(t2.val, 5005)
from(
SELECT 336.6 as val UNION ALL
SELECT 5005
) as t2
當您在內部查詢中運行沒有NULL的語句時,SQL從不評估5005,因此它不會達到需要將5005放入數字(4,1)字段的條件。
select IsNull(t2.val, 5005)
from(
SELECT 336.6 as val
) as t2
我認為問題是當SQL Server解析聯合時,它決定一個只有大到足以適合333.6( decimal(4,1)
)的十進制類型。 試圖將5005放入其中會導致溢出。
您可以自己解決指定十進制精度的問題:
select IsNull(t2.val, 5005)
from(
SELECT CONVERT(DECIMAL(5,1), 336.6) as val UNION ALL
SELECT NULL
) as t2
我相信它是因為您的336.6值被推斷為數據類型為NUMERIC。 如果你想更具體,那么明確將它轉換為DECIMAL;
SELECT IsNull(t2.val, CAST(5005 AS DECIMAL))
FROM (
SELECT CAST(336.6 AS DECIMAL) AS val
UNION ALL
SELECT NULL
) AS t2
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.