3

我正在尝试从 Oracle 11g 数据库中选择一些记录。该语句用于为 HTML 表实现某种“过滤”功能。

要求:限制分页和排序过滤结果。

查询是用Zend_Db_Select创建的

*像魅力一样工作: *

$select->where('APPLICATIONS LIKE ?', '%MYAPP1%');
$select->where('APPLICATIONS NOT LIKE ?', '%GENESIS%');
$select->limit(20);

= 1 个匹配结果(没关系!)

当我尝试对过滤结果进行排序时会出现问题:

$select->order('PATH ASC');

= 3 个匹配结果 ??

我认为它与 Zend DB Select 生成的查询有关,它看起来像这样:

 SELECT z2.*
    FROM (
        SELECT z1.*, ROWNUM AS "zend_db_rownum"
        FROM (
            SELECT "APPS".* FROM "APPS" WHERE (APPLICATIONS LIKE '%MYAPP1%') AND (APPLICATIONS NOT LIKE '%GENESIS%') ORDER BY "PATH" ASC
        ) z1
    ) z2
    WHERE z2."zend_db_rownum" BETWEEN 1 AND 20
  • 如果我在没有订单的情况下运行查询,一切都很好。
  • 如果我无限制地运行查询,一切都很好。
  • 如果我使用 order + limit -> 错误结果运行查询。

如果我接受声明并将订单放在“BETWEEN 1 AND 20”之后,它就像我想要的那样工作。但是Zend DB Select 怎么改呢?

重要提示:我正在对 Oracle VIEW 进行查询,如果我对“表”进行查询,它也可以。

4

2 回答 2

2

显然,Oracle 对查询的解释并不是 Zend 框架的意图:Oracle 似乎在排序之前将 ROWNUM 与内部查询的行号计数相关联,因此别名 zend_db_rownum 在外部查询的 where 子句中提供了错误的数字。

由于我们无法控制 Zend 框架生成 SQL 以响应 limit() 指令的方式,所以我能想到的唯一解决方法是跳过Zend limit() 指令,而是按照以下方式进行操作:

$select->where('APPLICATIONS LIKE ?', '%MYAPP1%');
$select->where('APPLICATIONS NOT LIKE ?', '%GENESIS%');
$select->order('PATH ASC');

$sql = $select->__toString();

$sql = "select * from (" . $sql . ") where ROWNUM between 1 and 20";

$stmt = $db->query( $sql, array());
$result = $stmt->fetchAll();

当然,这种解决方法仅在您不开发跨数据库的情况下合法,因此您的代码不必与数据库无关。这意味着,如果您使用我建议的解决方法,您将限制您对 Oracle 的解决方案。

于 2013-02-27T14:16:46.213 回答
0

如果你检查SQL生成没有错误,并且WHERE子句确实没有不同的条件,可能是Oracle服务器错误。要检查它,请在不同的 Oracle 服务器版本或不同的 Oracle 服务器补丁级别上尝试。

于 2013-02-23T23:24:32.323 回答