INT和单个连字符( - )的奇怪CAST行为

Shn*_*ugo 5 t-sql sql-server int casting

我刚刚回答了这个问题:SQL中的Concate主键

我遇到了一个奇怪的行为:

SELECT 5 + '-' +  8 
Run Code Online (Sandbox Code Playgroud)

返回13

SELECT CAST('-' AS INT) 
Run Code Online (Sandbox Code Playgroud)

返回0,解释了以上内容......

但是:为什么一个连字符会被隐含地归零?

顺便说一下:单个+或(多个)空白字符串也一样......

这与CAST连字符( - )与Decimal相关,但指出这样一个事实,即转换为十进制不会产生这些结果......

dii*_*___ 5

这与负数和正数有关。我通过检查得出了这个结论ISNUMERIC

SELECT ISNUMERIC('-12')  // Result: 1
SELECT ISNUMERIC('+12')  // Result: 1
SELECT ISNUMERIC('.12')  // Result: 1 (because "." can be cast to MONEY)
Run Code Online (Sandbox Code Playgroud)

所以在你的情况下SELECT CAST('-' AS INT)会得到“负0”。甚至SELECT CAST('-.' AS MONEY)是合法的。


All*_*sen 5

我写这个作为答案,因为评论太长/太复杂 - 但它是基于我的评论.还要注意 - 我没有正式的来源,所以没有确认我的逻辑是"什么实施".(但我觉得有道理:))

但是假设您正在编写需要执行的转换函数.

所以你有一个要验证的字符串 - 例如,CAST('-50' AS INT);
然后单独取每个字符:

`-` is a valid part of the conversion, so move to next character.  
`5` is a valid part of the conversion, so move to next character.  
`0` is a valid part of the conversion, so move to next character.  
Done.
Run Code Online (Sandbox Code Playgroud)

所以假设字符串 CAST('-' AS INT);:

`-` is a valid part of the conversion, so move to next character.  
Done.
Run Code Online (Sandbox Code Playgroud)

现在 - 您可以进行额外的检查以使其无效,因为-不允许独立,但这需要额外的代码.

+空格相似.与货币和货币或期间和金钱相同:

SELECT CAST('$' AS MONEY)
SELECT CAST('.' AS MONEY)
Run Code Online (Sandbox Code Playgroud)

两者都是有效字符 - 但实际上只与实际数字有关.但他们解析 - 表明这一切都是故意的,转换的速度似乎是明智的.