Zend_Db_Adapter_Oracle:选择ORDER BY,LIMIT&哪里

时间:2013-02-21 08:38:26

标签: php sql oracle zend-framework

我正在尝试从Oracle 11g数据库中选择一些记录。 Statement用于为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
  • 如果我在没有订单的情况下运行查询,一切都很好。
  • 如果我无限制地运行查询,一切都很好。
  • 如果我使用订单+限制运行查询 - >错误的结果。

如果我接受声明并在“BETWEEN 1和20”之后下订单,它就像我想要的那样。但是如何说Zend DB选择改变呢?

重要提示:我正在对Oracle VIEW进行查询,如果我针对“表”进行查询,它也会起作用。

2 个答案:

答案 0 :(得分:2)

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

由于我们无法控制Zend框架响应limit()指令生成SQL的方式,因此我能想到的唯一解决方法是 跳过 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();

当然,如果您开发跨数据库,此解决方法合法,因此您的代码不必是DB 不可知即可。 这意味着,如果您使用我建议的解决方法,您将限制您的Oracle解决方案。

答案 1 :(得分:0)

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