在SQL Server中将空字符串CAST/CONVERT转换为INT

Nic*_*ick 8 sql-server

我遇到了一个我使用CAST(Col1 AS INT) + CAST(Col2 AS INT)Col1和Col2 的错误,VARCHAR当Col1或Col2空白时我得到了有效的结果,我没想到这个.我检查过,CAST(和CONVERT)都有这种用0替换空白的默认行为:

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

我检查了信息页面,我看不到任何引用来解释为什么这是行为(或通过服务器设置更改它).我当然可以解决这个问题,但我想问为什么这是行为,因为我不认为它是直观的.

我实际上宁愿CAST失败或给予NULL,是否有一个服务器设置在哪里影响这个?

Tan*_*ner 7

考虑INT在SQL Server中.它可以是三个值之一:

  • 空值
  • 0
  • 不是0

因此,如果您正在转换/转换空字符串(您假设它是一个数字),则0是最合乎逻辑的值.它允许区分NULL和0.

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

我认为这是合乎逻辑的.

如果你这样做:

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

你会得到:

将varchar值'abc'转换为数据类型int时转换失败.

如果你确实希望处理空字符串,就像NULL使用NULLIF一样,Bogdan在他的回答中建议:

DECLARE @val VARCHAR(2) = ''

SELECT CAST(NULLIF(@val,'') AS INT)  -- produces NULL
Run Code Online (Sandbox Code Playgroud)

如果两个表达式不相等,则NULLIF返回第一个表达式.如果表达式相等,则NULLIF返回第一个表达式类型的空值.

最后,如果您的列存储INT值,则考虑更改其数据类型(INT如果可以).

  • 对不起,但我不同意。0 是一个有效数字,所以我不明白为什么它应该被视为特殊情况,我认为 INT 要么是 NULL,要么是一个整数。我认为强制转换以空白字符串失败会更直观,因为空白字符串既不是 NULL 也不是有效数字。如果这是逻辑行为,那么为什么使用 DECIMAL 数据类型的相同操作会产生错误而不是 0? (3认同)