我遇到了一个错误,我使用的是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
,是否有某个服务器设置影响了这个?
答案 0 :(得分:7)
考虑SQL Server中的INT
。它可以是三个值之一:
因此,如果你正在转换/转换一个空字符串,你假设它是一个数字,那么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)