【问题标题】:Yii CDbCommand queryAll() return wrong resultYii CDbCommand queryAll() 返回错误结果
【发布时间】:2013-12-30 10:20:54
【问题描述】:

我正在使用 Yii CDbCommand 从 mysql 获取结果。
我在 mysql 查询和 var_dump Yii 的 CDbCommand SQL 中都记录了 SQL。
一样的。 我通过 CDbCommand->queryAll() 得到结果。
但是结果和在phpMyAdmin中运行同样的SQL是不一样的。

> SELECT `referer_url_id` FROM `trend_referer` WHERE
> ((`site_id` = '45654' and `date` between '20131211' and '20131211'))
> GROUP BY `referer_url_id` LIMIT 6
> OFFSET 30;

这个 SQL。我从 queryAll 和 phpMyAdmin 得到 6 个结果。
但只有 3 个是相同的。其他 3 个不同。
有点奇怪。

编辑: 最奇怪的是,几分钟后这个问题就消失了。
并出现在另一个“LIMIT 6 OFFSET xx”中。
xx 并非始终相同。
所以我认为这是 PDO 或 Yii 中的任何缓存机制?

【问题讨论】:

  • 在'20131211'和'20131211'之间尝试(date)`
  • 您期望得到什么样的答案?那个 queryAll 伪造了从数据库返回的一些结果?
  • ->queryAll() 不会神奇地重写您的原始查询以获得不同的结果。如果在多次运行同一个查询时得到不同的结果,这意味着查询中的某些内容(结果排序顺序)不是确定性的。你为什么使用GROUP BY 而不是ORDER BY?表架构是什么样的?
  • 改成LIMIT 30, 6
  • phpMyAdmin 的结果是正确的。但是 queryAll() 返回错误的结果。

标签: php yii pdo pdostatement


【解决方案1】:

试试这个

SELECT `referer_url_id` FROM `trend_referer` WHERE
((`site_id` = '45654' and (`date` between '20131211' and '20131211')) )
GROUP BY `referer_url_id` LIMIT 6
OFFSET 30;

date between '20131211' and '20131211'周围添加圆括号

编辑:

对于偏移错误'LIMIT 6 OFFSET xx'。

将您的查询更改为

GROUP BY `referer_url_id` LIMIT 30, 6

【讨论】:

  • 这不是 sql 问题。我得到了 6 个结果,其中 3 个是相同的,而 queryAll() 和 phpMyAdmin 有 3 个不同。 phpMyAdmin 结果是正确的。 queryAll() 返回错误的结果。
  • 改成LIMIT 30, 6
【解决方案2】:

我知道是什么问题。因为 Yii CDbCommand.php 的 buildQuery() 函数加入 SQL 使用 "\n" 作为换行符而不是空格。
例如。

SELECT * FROM table WHERE 1=1 GROUP BY field;

会变成

SELECT *\nFROM table\nWHERE 1=1\nGROUP BY field;

这会导致不同的结果。
我修改 buildQuery()。将“\n”替换为空格。我可以得到正确的结果集。

我正在测试 MySQL-5.5.18-log 版本。我不知道是 MySQL 的 bug 还是 Yii 的问题。

【讨论】:

  • 这显然不是问题。可能是您之前猜到的某种缓存。
猜你喜欢
  • 2016-09-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-05
  • 2020-04-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多