2012-02-03 80 views
31

最近有人問我這個問題,我想我會在Stack Overflow上發佈它以獲得一些輸入。爲什麼從int轉換/轉換返回星號

現在顯然以下兩種情況都應該失敗。

#1:

DECLARE @x BIGINT 
SET @x = 100 
SELECT CAST(@x AS VARCHAR(2)) 

明顯的錯誤:

Msg 8115, Level 16, State 2, Line 3
Arithmetic overflow error converting expression to data type varchar.

#2:

DECLARE @x INT 
SET @x = 100 
SELECT CAST(@x AS VARCHAR(2)) 

並不明顯,它返回一個*(人們會想到這是一個算術溢出以及???)


現在我真正的問題是,爲什麼?這是僅僅是設計還是有歷史或其他什麼 背後呢?

我看了幾個網站,不能得到滿意的答案。

例如 http://beyondrelational.com/quiz/sqlserver/tsql/2011/questions/Why-does-CAST-function-return-an-asterik--star.aspx

http://msdn.microsoft.com/en-us/library/aa226054(v=sql.80).aspx

請注意我知道/瞭解,當一個整數太大而被轉換成特定大小的字符串,這將是「轉化」成星號,這是明顯的答案,我希望我可以對所有不斷給出這個答案的人下決心。 我想知道爲什麼使用星號而不是拋出異常,例如歷史原因等?

+5

查找星號的十進制ASCII碼以解決「謎題」。 – dasblinkenlight 2012-02-03 05:24:16

+0

哈哈,42?宇宙和其他一切生命的答案? hehehe – Helix 2012-02-03 05:48:46

+6

@dasblinkenlight - 這解釋了爲什麼'select *'返回**所有** :)。 – 2012-02-03 06:41:26

回答

27

更好玩,試試這個:

DECLARE @i INT 
SET @i = 100 
SELECT CAST(@i AS VARCHAR(2)) -- result: '*' 
go 

DECLARE @i INT 
SET @i = 100 
SELECT CAST(@i AS NVARCHAR(2)) -- result: Arithmetic overflow error 

:)


回答你的查詢是: 「歷史原因」

的數據類型INT和VARCHAR比BIGINT和NVARCHAR早。 很多較舊。實際上,它們在原始 SQL規範中。同樣較老的是用星號替換輸出的異常抑制方法。

之後,SQL人員決定拋出一個錯誤比替換僞造(通常是混淆)的輸出字符串更好/更一致等。但是,爲了保持一致性,他們保留了先前的數據類型組合的先前行爲(以免破壞現有代碼)。 (很多)後來,當添加BIGINT和NVARCHAR數據類型時,他們得到了新的(呃)行爲,因爲它們沒有被上面提到的祖先覆蓋。

+1

真棒,懷疑是這樣的,但只是想要一些真正的確認,謝謝 – Helix 2012-04-13 06:42:25

+0

我想有一個鏈接到MS SQL Server的轉換表和版本參考。 – Markus 2014-07-24 06:43:04

+1

這是一個很好的答案。我們在這裏遇到了類似的問題,將6,7和8位數的INT轉換爲CHAR(6),結果爲7或8的星號。我們希望得到一個錯誤,並讓我們的進程不導入這些數據。我們收到一個錯誤,但數據仍然是導入的,只是用星號替換這部分: ** ErrorMessage:字符串或二進制數據將被截斷。 ErrorSeverity:16 ErrorState:14 ** – Brien 2015-10-22 15:37:06

0

您可以在「截斷和舍入結果」部分的CAST and CONVERT頁面上閱讀。 當轉換爲char或varchar時,當結果長度太短而不能顯示時,int,smallint和tinyint將返回*。其他數字到字符串轉換將返回一個錯誤。