在SQL Server

时间:2016-05-27 08:21:34

标签: 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, '')

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

我实际上这个CAST失败了或者给了NULL,是否有某个服务器设置影响了这个?

4 个答案:

答案 0 :(得分:7)

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

  • NULL
  • 0
  • 不是0

因此,如果你正在转换/转换一个空字符串,你假设它是一个数字,那么0是最合乎逻辑的值。它允许区分NULL和0。

SELECT CAST(NULL AS INT) -- NULL
SELECT CAST('' AS INT)   -- 0
SELECT CAST('42' AS INT) -- 42

我认为这是合乎逻辑的。

如果你这样做了:

SELECT CAST('abc' AS INT)

你会得到:

  

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

如果您希望以NULL处理空字符串,请使用NULLIF作为Bogdan suggests in his answer

DECLARE @val VARCHAR(2) = ''

SELECT CAST(NULLIF(@val,'') AS INT)  -- produces NULL
  

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

最后,如果您的列存储INT值,请考虑将其数据类型更改为INT

答案 1 :(得分:2)

假设当空字符串转换到INT时你得到什么,那么我将使用以下解决方案之一:

DECLARE @SourceString VARCHAR(50) = ''

SELECT CONVERT(INT, NULLIF(@SourceString, ''))  AS Solution1
SELECT TRY_PARSE(@SourceString AS INT)          AS Solution2

答案 2 :(得分:0)

您可能知道NULL是一个标记,表示数据值不存在。而''是一个值,空但值。

默认情况下,MS SQL将空值转换(或转换)为0。要解决此问题并将其显示为NULL,您可以使用NULLIF

简单示例:

SELECT  int_as_varchars as actual,
        cast(NULLIF(int_as_varchars,'') as int) as with_nullif,
        cast(int_as_varchars as int) as just_cast
FROM (VALUES
('1'),
(''),
(NULL),
('0')
) as t(int_as_varchars)

输出:

actual  with_nullif just_cast
1       1           1
        NULL        0
NULL    NULL        NULL
0       0           0

如您所见,在这种情况下,NULLIF会帮助您获取NULL而不是0

答案 3 :(得分:0)

那呢?

declare @t table(bucket bigint);

INSERT INTO @t VALUES (1);
INSERT INTO @t VALUES (2);
INSERT INTO @t VALUES (-1);
INSERT INTO @t VALUES (5);
INSERT INTO @t VALUES (0);

declare @Bucket bigint = 0 --filter by 0

select * from @t
where 1=1
AND ((@Bucket is Null or cast(@Bucket as nvarchar) = '') or bucket=@Bucket)