php - Zend_Db_Adapter_Oracle : Select with ORDER BY, 限制和位置

标签 php sql oracle zend-framework

我正在尝试从 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 进行查询,如果我针对“表”进行查询,它也能正常工作。

最佳答案

显然 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。

关于php - Zend_Db_Adapter_Oracle : Select with ORDER BY, 限制和位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14997786/

相关文章:

php - 无法使用 cURL 将文件作为表单数据发送

php - Slim + NotORM,选择 %Like%

php - 使用 PHP 保护获取的数据

mysql - 插入表 Mysql

mysql 右连接未按预期工作

java - 如何在 Spring Hibernate Oracle DB 中使用 WebLogic 配置的连接池(使用 JNDI 名称)

oracle - 在oracle中维护计划表

php - 从 JSON 编码的 PHP 传递 JavaScript 函数

java - 使用 ojdbc14.jar 插入 CLOB - JAVA

mysql - 基于年和月的存储过程选择