我正在尝试从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进行查询,如果我针对“表”进行查询,它也会起作用。
答案 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服务器补丁级别上尝试。