MYSQL QUERY ACTING STRANGE

时间:2013-07-24 18:52:04

标签: mysql innodb

所以我有这个查询

 SELECT COUNT(b.user_ticket_id) as tiketscount
 FROM event_tickets a
 INNER JOIN user_tickets b ON a.event_ticket_id = b.event_ticket_id
 WHERE b.status = 'used' AND a.event_id = '1'

给了我预期的结果(计数= 1),我决定尝试下面的代码查询

 SELECT COUNT(b.user_ticket_id) as tiketscount
 FROM event_tickets a
 INNER JOIN user_tickets b ON a.event_ticket_id = b.event_ticket_id
 WHERE b.status = 'used' AND a.event_id = '1  DROP TABLE contact "1=1"'

并且我得到了与之前相同的结果,但是当我将下一个更改为2时,没有结果,是否可能mysql使用它找到的第一个字符?

 SELECT COUNT(b.user_ticket_id) as tiketscount
 FROM event_tickets a
 INNER JOIN    user_tickets b ON a.event_ticket_id = b.event_ticket_id
 WHERE b.status = 'used' AND a.event_id = '2  DROP TABLE contact "1=1"'

任何人都知道为什么会这样吗?感谢

我正在使用MYSQL 5.5.30 InnoDB

3 个答案:

答案 0 :(得分:1)

event_id是某种类型的数字列类型(可能是INT),因此MySQL将您的字符串'1 DROP TABLE contact "1=1"'转换为1,使其与第一个查询相同。

在第三个查询中,它也最好转换值,并执行相同操作,将查询提取到:

SELECT COUNT(b.user_ticket_id) as tiketscount FROM event_tickets a INNER JOIN    user_tickets b ON a.event_ticket_id = b.event_ticket_id
WHERE b.status = 'used' AND a.event_id = 2

我认为没有event_id为2且status为'已使用'的记录。

如果您的专栏是INT而不是某种形式的文字,则无需将您的数字用引号括起来,实际上不鼓励。

答案 1 :(得分:1)

这是可能的,因为MySQL正在进行隐式数据转换。 MySQL正在将提供的字符串文字转换为数字。

作为正在发生的事情的演示,请尝试以下查询:

SELECT '123ABC  ' + 0
SELECT 'A1B2    ' + 0
SELECT '1.23D56 ' + 0
SELECT ' 78 90  ' + 0 

你会发现MySQL正在读取字符串文字,并将值转换为数值。它从字符串的最左边的字符开始,一次读取一个字符(从左到右),直到它到达字符串的末尾,或者直到它遇到导致字符串无法转换为数字值的字符为止

您也可以尝试使用示例中的字符串文字进行相同类型的查询,

 SELECT '1  DROP TABLE contact "1=1"' + 0 
 SELECT '2  DROP TABLE contact "1=1"' + 0 

分别返回1和2的数值。

这种行为似乎有点“奇怪”,因为其他数据库(如Oracle和SQL Server)会在某些相同的字符串转换为数字时抛出错误。 MySQL更宽松,并假设任何字符串值都可以转换为数字。

答案 2 :(得分:1)

一个简单的例子:

mysql> create table foo (id int);
mysql> insert into foo (id) values (1), (2), (3);
mysql> select id from foo where id='2 DROP TABLE';
+------+
| id   |
+------+
|    2 |
+------+
1 row in set, 1 warning (0.00 sec)

mysql> select id from foo where id='4 DROP TABLE';
Empty set, 1 warning (0.00 sec)

mysql> select id from foo where id='0 DROP TABLE';
Empty set, 1 warning (0.00 sec)

由于您的2 DROP TABLE ...字符串以数字开头,因此MySQL会“礼貌地”将其自动转换为int以匹配id字段。所以基本上保留了12,并且再次抛出字符串的其余部分。

请注意,当我使用04作为初始数字进行测试时,未找到任何行,因为没有包含ID为04的行桌子。

另请注意,MySQL正在发出警告。本案的案文是:

mysql> show warnings;
+---------+------+--------------------------------------------------+
| Level   | Code | Message                                          |
+---------+------+--------------------------------------------------+
| Warning | 1292 | Truncated incorrect DOUBLE value: '0 DROP TABLE' |
+---------+------+--------------------------------------------------+

所以,是的,MySQL只是截断你的“数字”的字符串部分。