2012-02-03 82 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将返回*。其他数字到字符串转换将返回一个错误。