sql - 查询返回空集 Mysql 5.1.49 但返回 5.0-ish 上的内容

标签 sql mysql

为了尝试自己解决这个问题,我进行了大量的搜索和故障排除。

我的情况是,我已经将主机从 Debian Lenny(5.0-ish)更新为 Debian Squeeze(MySQL 5.1.49),并且之前返回预期结果的工作查询现在返回一个空集。

所以这里继续介绍背景。为了查看数据是否有问题,我对数据库进行了mysqldump。然后我将其复制到我的开发机器(Mac OS X 10.6.8,通过 Homebrew 安装了 MySQL)并在那里设置数据库。查询返回了预期的结果!

该代码基于开源应用程序,因此我返回并在 Lenny 主机上进行了全新安装和数据库引导。我确认查询返回了预期的结果。

我还在 Squeeze 上全新安装了应用程序(未升级的主机)。开源应用程序 Squeeze 上的全新安装按预期工作。

我从 Lenny 上全新安装的应用程序中执行了 mysqldump。然后,我在干净的 Squeeze 主机上创建了一个新数据库并将 Lenny 转储加载到其中。查询不再返回预期的结果。与数据库升级到 Squeeze 的情况相同。

这里描述了数据的情况。

首先是表格:

mysql> describe roles;
+-------------------+-------------+------+-----+---------+----------------+
| Field             | Type        | Null | Key | Default | Extra          |
+-------------------+-------------+------+-----+---------+----------------+
| id                | int(11)     | NO   | PRI | NULL    | auto_increment |
| name              | varchar(40) | YES  |     | NULL    |                |
| authorizable_type | varchar(30) | YES  |     | NULL    |                |
| authorizable_id   | int(11)     | YES  |     | NULL    |                |
| created_at        | datetime    | YES  |     | NULL    |                |
| updated_at        | datetime    | YES  |     | NULL    |                |
+-------------------+-------------+------+-----+---------+----------------+

mysql> describe roles_users;
+------------+----------+------+-----+---------+-------+
| Field      | Type     | Null | Key | Default | Extra |
+------------+----------+------+-----+---------+-------+
| user_id    | int(11)  | YES  | MUL | NULL    |       |
| role_id    | int(11)  | YES  | MUL | NULL    |       |
| created_at | datetime | YES  |     | NULL    |       |
| updated_at | datetime | YES  |     | NULL    |       |
+------------+----------+------+-----+---------+-------+
4 rows in set (0.00 sec)

您猜对了,这些来自大约 Rails 2.1ish 的授权插件。现在由此时已升级到 Rails 2.3.5 的应用程序使用。

我已经验证了两台主机上的表描述是相同的。

下一个数据:

mysql> select * from roles where id = 1;
+----+------------+-------------------+-----------------+---------------------+---------------------+
| id | name       | authorizable_type | authorizable_id | created_at          | updated_at          |
+----+------------+-------------------+-----------------+---------------------+---------------------+
|  1 | site_admin | Basket            |               1 | 2009-05-27 00:14:22 | 2009-05-27 00:14:22 |
+----+------------+-------------------+-----------------+---------------------+---------------------+
1 row in set (0.00 sec)

mysql> select * from roles_users where role_id = 1 and user_id = 1;
+---------+---------+---------------------+---------------------+
| user_id | role_id | created_at          | updated_at          |
+---------+---------+---------------------+---------------------+
|       1 |       1 | 2009-05-27 00:14:22 | 2009-05-27 00:14:22 |
+---------+---------+---------------------+---------------------+
1 row in set (0.00 sec)

同样,两个主机返回相同的结果。

这是预期返回的查询(由授权插件构建以验证用户在系统中的正确对象上具有正确的角色):

mysql> SELECT `roles`.id FROM `roles` INNER JOIN `roles_users` ON `roles`.id = `roles_users`.role_id WHERE (`roles`.`id` = 1 ) AND ((`roles_users`.user_id = 1 )) LIMIT 1 ;
SELECT `roles`.id FROM `roles` INNER JOIN `roles_users` ON `roles`.id = `roles_users`.role_id WHERE (`roles`.`id` = 1 ) AND ((`roles_users`.user_id = 1 )) LIMIT 1 ;
+----+
| id |
+----+
|  1 |
+----+
1 row in set (0.00 sec)

又是在 Debian Squeeze 主机上,返回空集:

mysql> SELECT `roles`.id FROM `roles` INNER JOIN `roles_users` ON `roles`.id = `roles_users`.role_id WHERE (`roles`.`id` = 1 ) AND ((`roles_users`.user_id = 1 )) LIMIT 1 ;
Empty set (0.00 sec)

有什么想法吗?还有其他人遇到过这种情况吗?

更新评论请求的结果:

这里没有 LIMIT 1:

mysql> SELECT `roles`.id FROM `roles` INNER JOIN `roles_users` ON `roles`.id = `roles_users`.role_id WHERE (`roles`.`id` = 1 ) AND ((`roles_users`.user_id = 1 ));
Empty set (0.00 sec)

此处从 where 子句中删除 roles_users.user_id = 1:

mysql> SELECT `roles`.id FROM `roles` INNER JOIN `roles_users` ON `roles`.id = `roles_users`.role_id WHERE `roles`.`id` = 1 ;
+----+
| id |
+----+
|  1 |
...
3 rows in set (0.00 sec)

这是上面的查询,但在选择中显示了 roles_users.user_id:

mysql> SELECT `roles`.id, `roles_users`.user_id FROM `roles` INNER JOIN `roles_users` ON `roles`.id = `roles_users`.role_id WHERE `roles`.`id` = 1 ;
+----+---------+
| id | user_id |
+----+---------+
|  1 |       1 |
...
3 rows in set (0.00 sec

最后是从 where 子句中删除 roles.id,但保留 roles_users.user_id:

mysql> SELECT `roles`.id, `roles_users`.user_id FROM `roles` INNER JOIN `roles_users` ON `roles`.id = `roles_users`.role_id WHERE `roles_users`.user_id = 1;                                                                             
+----+---------+
| id | user_id |
+----+---------+
...
|  1 |       1 |
...
9 rows...

最佳答案

我已经找到导致此问题发生在 Debian Squeeze MySQL 5.1.49 上的根本原因;当 roles_users 表的 role_id 有多个不同的 user_id 时,查询将返回一个空集。

即如果我有这个:

mysql> SELECT `roles_users`.role_id, `roles_users`.user_id FROM `roles` INNER JOIN `roles_users` ON `roles`.id = `roles_users`.role_id order by role_id;
+---------+---------+
| role_id | user_id |
+---------+---------+
|       1 |       1 |
|       2 |       1 |
|       3 |       1 |
|       4 |       1 |
|       5 |       1 |
|       6 |       2 |
+---------+---------+
6 rows in set (0.01 sec)

我得到了我所期望的:

mysql> SELECT `roles`.id FROM `roles` INNER JOIN `roles_users` ON `roles`.id = `roles_users`.role_id WHERE (`roles`.`id` = 1) AND  ((`roles_users`.user_id = 1)) LIMIT 1;
+----+
| id |
+----+
|  1 |
+----+
1 row in set (0.00 sec)

但是当我有这个时(一个附加的 user_id 有 r​​ole_id 1):

mysql> SELECT `roles_users`.role_id, `roles_users`.user_id FROM `roles` INNER JOIN `roles_users` ON `roles`.id = `roles_users`.role_id order by role_id;
+---------+---------+
| role_id | user_id |
+---------+---------+
|       1 |       1 |
|       1 |       5 |
|       2 |       1 |
|       3 |       1 |
|       4 |       1 |
|       4 |       5 |
|       5 |       1 |
|       6 |       2 |
+---------+---------+
8 rows in set (0.00 sec)

我明白了:

mysql> SELECT `roles`.id FROM `roles` INNER JOIN `roles_users` ON `roles`.id = `roles_users`.role_id WHERE (`roles`.`id` = 1 ) AND ((`roles_users`.user_id = 1 )) LIMIT 1 ;
Empty set (0.00 sec)

所以有两种可能。

与该数据集(多个具有相同 role_id 的 user_id)一起工作的查询始终无效,并且 MySQL 5.0.51a-24+lenny4 无论如何都可以使用它,即使它不应该有或有一个MySQL 5.1.49-3 (Debian) 中的错误。

我将在论坛上报告 MySQl 的错误并查看我得到的响应。

关于sql - 查询返回空集 Mysql 5.1.49 但返回 5.0-ish 上的内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7102799/

相关文章:

android - 使用 ksoap2 将加密密码从 android 传递到 Web 服务到 mysql 数据库

mysql - CONCAT 与 IF ELSE 一起?

MySQL 自定义排序

Java Hibernate 为什么namedQuery上的executeUpdate首先执行全表更新?

mysql - 用于查询大数据集的最佳搜索查询和结构

mysql - 如何在各个表中查找列名

mysql - sql中每四个小时的平均数据?

mysql - 具有属性的产品的数据模型,每个属性组合具有不同的价格

python - Web2Py - 如何使用带有 WHERE.. IN 关键字的 SELECT 查询

mysql - SQL 方程当前减去其他年份?