ISNULL返回截断的字符串

时间:2014-09-09 20:14:36

标签: sql-server

我有一个不寻常的问题:

DECLARE @enabledClients TABLE(id int); --Some clients will have this setting enabled by default
DECLARE @enabled nvarchar(10);

INSERT INTO @enabledClients (id) SELECT [id] FROM dbo.client WHERE name IN ('FOO', 'BAR');

当我遍历每个客户端时,我想将@enabled设置为true或false:

WHILE @clientId IS NOT NULL
BEGIN
    SET @enabled = ISNULL((SELECT 'true' from @enabledClients where id = @clientId), 'false');
     ...
    SET @clientId = (SELECT MIN(clientId) FROM dbo.client WHERE id > @clientId);
END

如果客户是“FOO'或者' BAR',@enabled是真实的'正如所料。如果没有,@enabled就是' fals'。不是' false',我希望,但是4个字符的字符串' fals'。为什么会这样?

2 个答案:

答案 0 :(得分:4)

ISNULL返回第一个参数的数据类型的结果。字符串文字“true”被视为varchar(4)

您可以使用coalesce获得所需的结果,但will execute the query twice

您可以坚持使用isnull并将第一个查询中的文字投射到varchar(5)以避免此问题。

cast('true' as varchar(5))

答案 1 :(得分:0)

经过长时间研究为什么包含 ISNULL() 的复杂查询有时会失败后,我刚刚发现了同样的事情。 ISNULL() 与字符数据一起使用显然是危险的,只要逗号后面的计算结果长度大于 1! 如果逗号后面的计算结果超过一个字符,那么程序员必须小心它的计算结果不大于逗号的大小。我之前对 ISNULL 的理解是,逗号之后的内容将替换逗号之前的内容,如果逗号之前的内容计算为 NULL。但事实证明这是错误的。事实证明,逗号之后的任何内容都将转换为逗号之前的任何内容的格式,然后替换 NULL 值。我写了一个查询来很好地证明这一点:

/* 
With commented line left out, result is "54321"
Uncommenting the line produces "12345" NOT "1234567890"
*/

DECLARE @First VARCHAR(5) = '54321'
DECLARE @Second VARCHAR(10) = '1234567890'

--SET @First = NULL

SELECT ISNULL(@First, @Second)