我有一张这样的表:
CREATE TABLE IF NOT EXISTS `session` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`token` varchar(32) NOT NULL,
`profile` varchar(1000) NOT NULL,
`created_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=41 ;
以及此表中的一些数据:
(38, '395d5feaf28df01aafe0781a7f34acbe', 'a:3:{s:2:"id";s:1:"2";s:8:"username";s:7:"wanmeng";s:12:"created_time";s:19:"2011-11-18 19:37:33";}', '2011-12-03 14:14:35'),
(39, '0e0ca06ed9ad86937f190eb9544ac935', 'a:3:{s:2:"id";s:1:"1";s:8:"username";s:6:"delphi";s:12:"created_time";s:19:"2011-11-18 13:29:40";}', '2011-12-03 14:28:36'),
(31, '3cba76b97cf123009632bdaa5a306385', 'a:3:{s:2:"id";s:1:"1";s:8:"username";s:6:"delphi";s:12:"created_time";s:19:"2011-11-18 13:29:40";}', '2011-12-02 15:50:21'),
(30, 'fa356333dd3ee8f1b18b8bf0a827e34c', 'a:3:{s:2:"id";s:1:"1";s:8:"username";s:6:"delphi";s:12:"created_time";s:19:"2011-11-18 13:29:40";}', '2011-12-01 15:32:47')
当我执行查询时:SELECT * FROM session
WHERE token = false,我希望没有返回结果,但是mysql返回结果:
39 0e0ca06ed9ad86937f190eb9544ac935 a:3:{s:2:"id";s:1:"1";s:8:"username";s:6:"delphi";... 2011-12-03 22:28:36
30 fa356333dd3ee8f1b18b8bf0a827e34c a:3:{s:2:"id";s:1:"1";s:8:"username";s:6:"delphi";... 2011-12-01 23:32:47
似乎布尔值'false'可以匹配某些varchar,但是'fa356333dd3ee8f1b18b8bf0a827e34c'和'false'之间是否存在任何关系,为什么会这样?
答案 0 :(得分:5)
在MYSQL中,FALSE不是布尔值,它是一个整数,更具体地说是零。事实上,MySQL没有布尔列类型(它有BOOL
和BOOLEAN
,但它们只是TINYINT
的别名。因此,您的查询是以下内容的同义词:
SELECT * FROM session WHERE token = 0
由于token
是VARCHAR,因此MySQL需要将字符串转换为数字。运行此查询,您将了解规则:
SELECT
0 + "0001",
0 + "123abc",
0 + "abc123"
因此,fa356333dd3ee8f1b18b8bf0a827e34c
会转换为0
因为它以字母开头,因此匹配。
答案 1 :(得分:2)
您是否有任何理由未对token is null
或token like ''
进行测试?将varchar与false进行比较是一个坏主意,无论数据库是否会捕获您的错误...... varchar永远不会为false,false不等于null。
答案 2 :(得分:2)
如果要将布尔值与varchar进行比较,MySQL必须进行一些隐式类型转换。 MySQL将varchar值转换为布尔值,仅检查第一个字符。
如果字符是字符或数字0,则字符串将被计算为0,因此为假 如果字符是不同于0的数字,则字符串的计算结果为1,因此为True(并且不会出现在结果集中)
唯一要做的就是不要将字符串与布尔值进行比较,因为它没有任何意义。
答案 3 :(得分:1)
这应该是评论,但我没有足够的声誉......所以......
DelphiQin,您在评论中说,您正在将CI“get()”方法的结果传递给查询参数。我一直在那里,我通过在传递给查询之前将变量转换为字符串来解决:
(string)$my_var
这样,它将使用''(空字符串)而不是布尔值假。
我希望它可以帮助有同样问题的人。