在将WHERE条件应用于具有字符串值的整数字段时,我遇到了MySQL返回错误结果的问题。
CREATE TABLE `people` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1;
INSERT INTO `people` (`id`, `name`)
VALUES
(1, 'Bob'),
(2, 'Sally'),
(3, 'Jim');
现在我运行查询时:
SELECT *
FROM people
WHERE id = '1-abcd';
我的结果集是:
id name
1 Bob
一旦遇到非整数字符(在从字符串到INT的转换中),MySQL似乎在幕后将字符串值'1-abcd'截断为'1'。
你可能想知道为什么这很重要。我正在尝试修复一个用于PCI兼容性扫描的站点。扫描认为URI'/ some / page?id = 102-1'允许某种形式的续集注入,但实际上它在'/ some / page?id = 102'显示相同的内容。
这不是一个地方的问题。这是一个遍布整个地方的问题,而且它是一个相当大的系统。有什么方法可以在MySQL的结尾处纠正这个问题,所以它不再错误地判断这两个值是否等价?我查看了SQL模式的文档,但没有看到有关这种情况的任何内容。
更新:我向制作扫描的公司提出了争议,他们接受了扫描,所以我不再在树林里了。但令人失望的是,在这种情况下,显然没有办法将MySQL的转换行为从字符串配置为INT。 (您可以,但仅适用于INSERT和UPDATE。)
答案 0 :(得分:0)
MySQL类型将字符串文字值转换为整数会发生什么情况,当它执行该操作时,它从字符串的左边开始,一旦到达不能被视为数字一部分的字符,它就会剥离从那时起就把一切都搞定了。因此1-0将输出匹配赋予1.为此,您可以使用cast
。我不是100%肯定语法,但它是这样的:
select * from people
where id =
(
case when ISNUMERIC( '1-0' )
then cast ('1-0' as int)
else null
end )
这将做的是,如果它是一个数值,那么它将返回正确的匹配行,否则不会。
修改强>
以上查询似乎是MSSQL / Oracle,不适用于MySQL。对于MySQL,您可以使用RegExp。我从来没有使用过,但你可以在这里找到更多细节:
http://mysqlhints.blogspot.in/2012/01/how-to-find-out-if-entire-string-is.html
http://www.ash.burton.fm/blogs/2010/12/quick-tip-mysql-equivalent-of-isnumeric
http://www.justskins.com/forums/how-to-use-isnumeric-137604.html