为什么从int转换/转换返回星号

时间:2012-02-03 05:20:44

标签: sql-server tsql

有人最近问了我这个问题,我想我会把它发布在Stack Overflow上以获取一些意见。

现在显然以下两种情况都应该失败。

#1:

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

明显的错误:

  

Msg 8115,Level 16,State 2,Line 3
  将表达式转换为数据类型varchar的算术溢出错误。

#2:

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

不明显,它返回一个*(人们会认为这也是一个算术溢出?)


现在我真正的问题是,为什么???这仅仅是设计还是有历史或其他东西 在这背后阴险?

我看了几个网站,得不到满意的答案。

e.g。 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

请注意我知道/了解当一个整数太大而无法转换为特定大小的字符串,它将被“转换”为星号时,这是明显的答案,我希望我可以向所有人投票继续给出这个答案。 我想知道为什么使用星号而不是抛出异常,例如历史原因等??

2 个答案:

答案 0 :(得分:34)

要获得更多乐趣,请尝试以下方法:

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 :(得分:2)

您可以在“截断和舍入结果”部分的CAST and CONVERT页面上阅读。 当结果长度太短而无法在转换为char或varchar时显示时,Int,smallint和tinyint将返回*。其他数字到字符串转换将返回错误。