我想查找某个字符串字段不是空白或 null 的记录,所以我简单地写了SELECT ... FROM myTable WHERE x
,假设空白和 null 字符串的计算结果为 false,但情况似乎并非如此。
字符串“02306”为真,而“N06097EIP”不知何故为假。
这是怎么回事?
编辑:我知道解决方法,我只是想知道铸造是如何工作的。
在这些表达式中,字符串首先被转换为数字。"02306" 被转换为 >0 的 2306,因此被视为true
,而 "N06097EIP"(以非数字开头)被转换为 0,被评估为false
。
比较结果:
select convert("N06097EIP",signed)
和
select convert("02306",signed)
在布尔上下文中,例如
WHERE x
表达式x
将被评估为整数值。请注意,MySQL 将 BOOLEAN 视为数字类型。
http://dev.mysql.com/doc/refman/5.1/en/numeric-type-overview.html
表达式的类型无关紧要x
。根据文档化的转换规则,它要么是 INTEGER 类型,要么将转换为 INTEGER 类型。
最终结果是表达式x
将被评估为 NULL、整数零或非零整数。
这些对应于 NULL、FALSE 和 TRUE 的布尔“真实性”值。
之所以'02306'
认为 TRUE 是因为此字符串转换为非零的整数值 2306。
被认为是 FALSE的原因'N06097EIP'
是因为此字符串转换为整数值 0。
可以运行一个简单的测试用例来验证:
SELECT IF( 0 = 'N06097EIP', 'is zero', 'is not zero')
SELECT 0 = 'N06097EIP'
您观察到的行为完全是意料之中的。这一切都很简单。您可能没有意识到,因为规范模式是让我们避免这种类型的评估,而是使用“解决方法”(如您所说)返回布尔值。
不要试图用语法快捷方式对此过于可爱。如果不出意外,下一个必须弄清楚你在做什么的开发人员总是更难。
只需说出你想要的。
SELECT *
FROM myTable
WHERE x IS NOT NULL AND x <> '';
或者,如果您愿意:
SELECT *
FROM myTable
WHERE COALESCE(x, '') <> '';