ThinkPHP3.1.2的DbOracle.class.php不能实现分页的解决方法
2013-06-26 10:39
656 查看
ThinkPHP3.1.2的DbOracle.class.php不能分页的解决办法
我们发现, 在解析Limit的方法中, 存在一处错误, TP/Extend/Driver/Db/DbOracle.class.php
parseLimit()方法生成limit条件是错的! 我们先不修改这里的代码!
接着看, TP/Lib/Core/Db.class.php 中的 buildSelectSql() 方法, 其中这句是生成sql字符串的:
这涉及到了另一个方法 parseSql() !
我们在 Db.class.php 中找到它, 这个方法实际就是用 $options 分别替换 select 语句中的变量,
如果我们把 limit 相关的替换给注释掉, 然后组装成我们正确的sql语句, 那就OK了!
最终代码如下, 其中标注 edited 和 added 是修改或新增的代码:
--------------------------------------------------------------
最后, 修补一个小bug, TP/Lib/Core/Db.class.php 中的 buildSelectSql() 方法, 其中代码块
中的 strpos 函数返回可能为 0 , 所以不能那样判断, 必须改成
就OK了!
我们发现, 在解析Limit的方法中, 存在一处错误, TP/Extend/Driver/Db/DbOracle.class.php
public function parseLimit($limit) { $limitStr = ''; if(!empty($limit)) { $limit = explode(',',$limit); if(count($limit)>1) $limitStr = "(numrow>" . $limit[0] . ") AND (numrow<=" . ($limit[0]+$limit[1]) . ")"; else $limitStr = "(numrow>0 AND numrow<=".$limit[0].")"; // 这种方法实现分页, 是错的! } return $limitStr?' WHERE '.$limitStr:''; }
parseLimit()方法生成limit条件是错的! 我们先不修改这里的代码!
接着看, TP/Lib/Core/Db.class.php 中的 buildSelectSql() 方法, 其中这句是生成sql字符串的:
$sql = $this->parseSql ( $this->selectSql, $options );
这涉及到了另一个方法 parseSql() !
我们在 Db.class.php 中找到它, 这个方法实际就是用 $options 分别替换 select 语句中的变量,
如果我们把 limit 相关的替换给注释掉, 然后组装成我们正确的sql语句, 那就OK了!
最终代码如下, 其中标注 edited 和 added 是修改或新增的代码:
public function parseSql($sql, $options = array()) { $sql = str_replace ( array ( '%TABLE%', '%DISTINCT%', '%FIELD%', '%JOIN%', '%WHERE%', '%GROUP%', '%HAVING%', '%ORDER%', // '%LIMIT%', // edited '%UNION%', '%COMMENT%' ), array ( $this->parseTable ( $options ['table'] ), $this->parseDistinct ( isset ( $options ['distinct'] ) ? $options ['distinct'] : false ), $this->parseField ( ! empty ( $options ['field'] ) ? $options ['field'] : '*' ), $this->parseJoin ( ! empty ( $options ['join'] ) ? $options ['join'] : '' ), $this->parseWhere ( ! empty ( $options ['where'] ) ? $options ['where'] : '' ), $this->parseGroup ( ! empty ( $options ['group'] ) ? $options ['group'] : '' ), $this->parseHaving ( ! empty ( $options ['having'] ) ? $options ['having'] : '' ), $this->parseOrder ( ! empty ( $options ['order'] ) ? $options ['order'] : '' ), // $this->parseLimit ( ! empty ( $options ['limit'] ) ? $options['limit'] : '' ), // edited $this->parseUnion ( ! empty ( $options ['union'] ) ? $options ['union'] : '' ), $this->parseComment ( ! empty ( $options ['comment'] ) ? $options ['comment'] : '' ) ), $sql ); // added [ list ( $r1, $r2 ) = explode ( ',', $options ['limit'] ); $r2 = $r1 + $r2; if( '' !== $r1 ){ // page() 方法存在时 if (1 == $r1) { // limit 1 $sql = " SELECT * FROM (SELECT E.*, ROWNUM rn FROM ({$sql}) E WHERE ROWNUM <= 1) WHERE rn >= 1 "; } else { // x < rounum < y $sql = " SELECT * FROM (SELECT E.*, ROWNUM rn FROM ({$sql}) E WHERE ROWNUM <= {$r2}) WHERE rn > {$r1} "; } } // added ] return $sql; }
--------------------------------------------------------------
最后, 修补一个小bug, TP/Lib/Core/Db.class.php 中的 buildSelectSql() 方法, 其中代码块
if ( strpos ( $options['page'],',' ) ) { list ( $page, $listRows ) = explode ( ',', $options ['page'] ); } else { $page = $options ['page']; }
中的 strpos 函数返回可能为 0 , 所以不能那样判断, 必须改成
if( false !== strpos($options['page'], ',') )
就OK了!
相关文章推荐
- ThinkPHP3.1.2中DbOracle.class.php不能实现事务处理的解决方法
- Windows不能在本地计算机启动OracleDBConsoleorcl.错误代码2的解决方法
- 【php】thinkphp以post方式查询时分页失效的解决方法
- Oracle的OracleDBConsole 不能启动的又一解决新方法
- Oracledbconsole服务不能启动的解决方法
- php怎么写分页?怎么灵活实现分页的方法,快速在thinkphp里面实现分页
- thinkphp使用JWT-PHP时找不到类解决方法
- 针对oracle的分页解决方法
- oracle进行order by,排序字段值相同时,导致分页数据出现相同,加入rowid的解决方法
- Orabbix无法获取Oracle DB Size和DB Files Size的解决方法
- thinkphp在nginx没有pathinfo的情况出现.php的URL的解决方法
- php生成静态html分页实现方法
- php pdo oracle中文乱码的快速解决方法
- oracle 11g不能导出空表的多种解决方法
- ThinkPHP 3.2 PHPExcel 导入导出文件 第三方类库不能用问题解决
- windows下PHP不能开启pgsql扩展的解决方法
- php pdo oracle中文乱码的快速解决方法
- 使用php+apc实现上传进度条且在IE7下不显示的问题解决方法
- 不能“在oracle db server上使用sqlplus / as sysdba”的解决办法
- 在一个程序中需要用到全局变量(在多个class之间共享数据),请问如何定义具有这种功能的变量?或者是否有其他的方法解决多个class之间的数据共享(尽量简单实现)。 首先应该明确 Java中没有全局变