我有一个不寻常的问题:
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'。为什么会这样?
答案 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)