我只是尝试使用Oracle数据库并在分页中发现问题。 上次我在MySQL中使用时效果很好。
请参阅我的代码:
<?php
$page = $_POST['page'];
$cur_page = $page;
$page -= 1;
$per_page = 3;
$previous_btn = true;
$next_btn = true;
$first_btn = true;
$last_btn = true;
$start = $page * $per_page;
$query_pag_data = "SELECT P.FORM_NO, P.MODEL_NO, P.PRODUCTION_STATUS, P.REMARKS, P.DATE_ADDED, P.TIME, P.QTY_PLAN, M.MODEL_NO, M.MODEL_NAME
FROM SEIAPPS_PRODUCTION_STATUS P, SEIAPPS_MODEL M
WHERE ROWNUM BETWEEN $start AND $per_page AND P.MODEL_NO = M.MODEL_NO ORDER BY P.DATE_ADDED DESC, P.TIME";
$result_pag_data = oci_parse($c1, $query_pag_data);
oci_execute($result_pag_data);
我已经使用过ROWNUM,但是当我想打开第2页或下一页时,它没有显示任何数据。而表中仍有更多数据。
任何人都可以提供建议。 感谢
答案 0 :(得分:2)
ROWNUM
与MySQL中的LIMIT
不同。
在MySQL,
LIMIT
子句可用于约束SELECT
语句返回的行数...使用两个参数,第一个参数指定要返回的第一行的偏移量,以及second指定要返回的最大行数。初始行的偏移量为0(不是1):
SELECT * FROM tbl LIMIT 5,10; # Retrieve rows 6-15
在Oracle,
对于查询返回的每一行,
ROWNUM
伪列返回一个数字,表示Oracle从一个表或一组连接的行中选择行的顺序。选中的第一行的ROWNUM
为1,第二行为2,依此类推。
SELECT *
FROM (SELECT * FROM employees ORDER BY employee_id)
WHERE ROWNUM < 11;
在前面的示例中,
ROWNUM
值是顶级SELECT
语句的值,因此它们是在子查询中employee_id已经对这些行进行排序后生成的。
所以代码的问题是:
WHERE ROWNUM BETWEEN :startrow AND :perpage
在逻辑上不正确,因为ROWNUM
是行索引指示符,而不是“行数”指示符。 ROWNUM BETWEEN a AND b
表示返回从a到b排序的行,例如第1行到第3行,不第1行和第3行。
即使ROWNUM BETWEEN a AND b
有效(实际上没有),要获得查询的“第2页”,逻辑上您需要ROWNUM BETWEEN :startrow AND :endrow
,例如ROWNUM BETWEEN 4 AND 6
;
ROWNUM BETWEEN :startrow AND :endrow
实际上不适用于大于1的起始行,因为ROWNUM
是一个伪列,表示所选集合中行的顺序 ,
所以当你执行例如SELECT...WHERE ROWNUM BETWEEN 4 AND 6
,
ROWNUM
如果选择将为1 ,因此Oracle放弃了它; 根本没有结果。
要获得欲望输出,您必须将查询包装在子查询中,并检查外部的行号,如下所示:
SELECT * FROM
(SELECT ROWNUM rn, t.*
FROM
(SELECT ...
FROM ...
WHERE ...
ORDER BY ...) t
)
WHERE rn>=:startrow AND rn<=:endrow
保证在检查行顺序之前确定行排序。
Binding允许数据库重用声明上下文和语句的先前执行中的缓存,... Binding减少了SQL注入问题,因为与绑定变量关联的数据永远不会被视为SQL语句的一部分。
$statement=oci_parse("... WHERE rn>=:start AND rn<=:end");
oci_bind_by_name($statement,":start",$start,-1,SQLT_INT);
oci_bind_by_name($statement,":end",intval($start+$per_page-1),-1,SQLT_INT);
oci_execute($statement);