我正在为客户的网站编写灵活的搜索机制。我正在利用union子句查询数据库中的许多不同字段,以搜索用户输入的字符串值。除了一个问题,这个工作正常。
将文本字符串与当前设置为零的整数进行比较时,匹配始终返回true。换句话说,根据MySQL,“email@example.com”等于0。
我已经尝试利用CAST和CONVERT函数将其转换为标准字符串到字符串比较,但我似乎无法正确使用语法。我的尝试要么重复上述问题,要么在某些应该匹配时根本不返回任何行。我也担心这样做会对性能产生影响,因为我结合了许多工会。
我真正需要的是对输入的字符串与数据库中的值进行严格比较,无论是整数还是字符串。
编辑: 这是一个例子。
CREATE TABLE `test_table` (
`id` INT NOT NULL AUTO_INCREMENT ,
`email` VARCHAR(255) NOT NULL ,
`phone` BIGINT(19) NOT NULL DEFAULT '0' ,
PRIMARY KEY (`id`) )
ENGINE = MyISAM;
INSERT INTO `test_table` (`id`, `email`, `phone`) VALUES (1, 'email@example.com', 0);
SELECT * FROM test_table WHERE phone = 'email@example.com';
执行此操作,将返回已插入的一行。我的问题是它不应该!
答案 0 :(得分:1)
此查询应失败:
SELECT * FROM test_table WHERE cast(phone as char) = 'email@example.com';
原始问题的原因是,在比较字符串和数字时,它会将字符串转换为数字(因此您可以编写where phone = '123'
)。您需要使用字段的显式强制转换来使其成为字符串到字符串的比较,以防止此默认转换。
不幸的是,像这样的强制转换可能会阻止它使用索引。即使该字段已经char
,该演员也明显阻止其编入索引。
您也可以在输入验证期间解决它:如果phone
是整数,则不允许用户在搜索字段中提供非整数值。
答案 1 :(得分:0)
如何更换:
SELECT * FROM test_table WHERE phone = 'email@example.com'
使用:
SELECT * FROM test_table WHERE phone = 'email@example.com' and phone <> 0
&LT;&GT;意思是不同于。
这对您有用,因为您在电话栏中使用0表示没有电话号码(尽管在没有电话号码时使用NULL会更好。)