簡體   English   中英

為什么此SQL查詢失敗

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM