zend db 多表查询 LIMIT BUG 解决方法
2010-01-28 17:35
232 查看
zend db 多表查询 LIMIT BUG 解决方法
将Zend/Db/Adapter/Pdo/mssql.php中 如下方法替换 。
public function limit($sql, $count, $offset = 0)
{
$count = intval($count);
if ($count <= 0) {
/** @see Zend_Db_Adapter_Exception */
require_once 'Zend/Db/Adapter/Exception.php';
throw new Zend_Db_Adapter_Exception("LIMIT argument count=$count is not valid");
}
$offset = intval($offset);
if ($offset < 0) {
/** @see Zend_Db_Adapter_Exception */
require_once 'Zend/Db/Adapter/Exception.php';
throw new Zend_Db_Adapter_Exception("LIMIT argument offset=$offset is not valid");
}
$sql = preg_replace(
'/^SELECT/s+(DISTINCT/s)?/i',
'SELECT $1TOP ' . ($count+$offset) . ' ',
$sql
);
if ($offset > 0) {
$orderby = stristr($sql, 'ORDER BY');
$mtype = stristr($sql, 'INNER JOIN');//多表分页判断2010-01-28
if ($orderby !== false) {
$orderParts = explode(',', substr($orderby, 8));
$pregReplaceCount = null;
$orderbyInverseParts = array();
$orderbyInverseParts2 = array();//
foreach ($orderParts as $orderPart) {
$orderPart = rtrim($orderPart);
//
if ($mtype!==false){
$inv2='"outer_tbl"'.stristr($orderPart, '.');
$orderbyInverseParts2[] = $inv2;
}
//
$inv = preg_replace('//s+desc$/i', ' ASC', $orderPart, 1, $pregReplaceCount);
if ($pregReplaceCount) {
//
if ($mtype!==false){
$inv='"inner_tbl"'.stristr($inv, '.');
}
//
$orderbyInverseParts[] = $inv;
continue;
}
$inv = preg_replace('//s+asc$/i', ' DESC', $orderPart, 1, $pregReplaceCount);
if ($pregReplaceCount) {
//
if ($mtype!==false){
$inv='"inner_tbl"'.stristr($inv, '.');
}
//
$orderbyInverseParts[] = $inv;
continue;
} else {
$orderbyInverseParts[] = $orderPart . ' DESC';
}
}
$orderbyInverse = 'ORDER BY ' . implode(', ', $orderbyInverseParts);
$orderbyInverse2 = 'ORDER BY ' . implode(', ', $orderbyInverseParts2);
}
$sql = 'SELECT * FROM (SELECT TOP ' . $count . ' * FROM (' . $sql . ') AS inner_tbl';
if ($orderby !== false) {
$sql .= ' ' . $orderbyInverse . ' ';
}
$sql .= ') AS outer_tbl';
if ($orderby !== false) {
//
if ($mtype!== false){
$sql .= ' ' . $orderbyInverse2 . ' ';
}else{
$sql .= ' ' . $orderby;
}
//
}
}
return $sql;
}
A SELECT "ts_cgb".*, "area_plan"."Name" FROM "ts_cgb"
INNER JOIN "area_plan" ON area_plan.Id = ts_cgb.PlanId WHERE (ts_cgb.Isbn like '%%') AND (ts_cgb.Sid = '1') AND (ts_cgb.CatalogId != '-1')
B SELECT * FROM (SELECT TOP 1 * FROM (SELECT TOP 11 "ts_cgb".*, "area_plan"."Name" FROM "ts_cgb"
INNER JOIN "area_plan" ON area_plan.Id = ts_cgb.PlanId WHERE (ts_cgb.Isbn like '%%') AND (ts_cgb.Sid = '1') AND (ts_cgb.CatalogId != '-1') ORDER BY "ts_cgb"."Id" ASC) AS inner_tbl ORDER BY "ts_cgb"."Id" DESC ) AS outer_tbl ORDER BY "ts_cgb"."Id" ASC
C SELECT * FROM (SELECT TOP 1 * FROM (SELECT TOP 11 "ts_cgb".*, "area_plan"."Name" FROM "ts_cgb"
INNER JOIN "area_plan" ON area_plan.Id = ts_cgb.PlanId WHERE (ts_cgb.Isbn like '%%') AND (ts_cgb.Sid = '1') AND (ts_cgb.CatalogId != '-1') ORDER BY "ts_cgb"."Id" ASC) AS inner_tbl ORDER BY "inner_tbl"."Id" DESC ) AS outer_tbl ORDER BY "outer_tbl"."Id" ASC
C 为修改后 正确处理SQL 效果。
将Zend/Db/Adapter/Pdo/mssql.php中 如下方法替换 。
public function limit($sql, $count, $offset = 0)
{
$count = intval($count);
if ($count <= 0) {
/** @see Zend_Db_Adapter_Exception */
require_once 'Zend/Db/Adapter/Exception.php';
throw new Zend_Db_Adapter_Exception("LIMIT argument count=$count is not valid");
}
$offset = intval($offset);
if ($offset < 0) {
/** @see Zend_Db_Adapter_Exception */
require_once 'Zend/Db/Adapter/Exception.php';
throw new Zend_Db_Adapter_Exception("LIMIT argument offset=$offset is not valid");
}
$sql = preg_replace(
'/^SELECT/s+(DISTINCT/s)?/i',
'SELECT $1TOP ' . ($count+$offset) . ' ',
$sql
);
if ($offset > 0) {
$orderby = stristr($sql, 'ORDER BY');
$mtype = stristr($sql, 'INNER JOIN');//多表分页判断2010-01-28
if ($orderby !== false) {
$orderParts = explode(',', substr($orderby, 8));
$pregReplaceCount = null;
$orderbyInverseParts = array();
$orderbyInverseParts2 = array();//
foreach ($orderParts as $orderPart) {
$orderPart = rtrim($orderPart);
//
if ($mtype!==false){
$inv2='"outer_tbl"'.stristr($orderPart, '.');
$orderbyInverseParts2[] = $inv2;
}
//
$inv = preg_replace('//s+desc$/i', ' ASC', $orderPart, 1, $pregReplaceCount);
if ($pregReplaceCount) {
//
if ($mtype!==false){
$inv='"inner_tbl"'.stristr($inv, '.');
}
//
$orderbyInverseParts[] = $inv;
continue;
}
$inv = preg_replace('//s+asc$/i', ' DESC', $orderPart, 1, $pregReplaceCount);
if ($pregReplaceCount) {
//
if ($mtype!==false){
$inv='"inner_tbl"'.stristr($inv, '.');
}
//
$orderbyInverseParts[] = $inv;
continue;
} else {
$orderbyInverseParts[] = $orderPart . ' DESC';
}
}
$orderbyInverse = 'ORDER BY ' . implode(', ', $orderbyInverseParts);
$orderbyInverse2 = 'ORDER BY ' . implode(', ', $orderbyInverseParts2);
}
$sql = 'SELECT * FROM (SELECT TOP ' . $count . ' * FROM (' . $sql . ') AS inner_tbl';
if ($orderby !== false) {
$sql .= ' ' . $orderbyInverse . ' ';
}
$sql .= ') AS outer_tbl';
if ($orderby !== false) {
//
if ($mtype!== false){
$sql .= ' ' . $orderbyInverse2 . ' ';
}else{
$sql .= ' ' . $orderby;
}
//
}
}
return $sql;
}
A SELECT "ts_cgb".*, "area_plan"."Name" FROM "ts_cgb"
INNER JOIN "area_plan" ON area_plan.Id = ts_cgb.PlanId WHERE (ts_cgb.Isbn like '%%') AND (ts_cgb.Sid = '1') AND (ts_cgb.CatalogId != '-1')
B SELECT * FROM (SELECT TOP 1 * FROM (SELECT TOP 11 "ts_cgb".*, "area_plan"."Name" FROM "ts_cgb"
INNER JOIN "area_plan" ON area_plan.Id = ts_cgb.PlanId WHERE (ts_cgb.Isbn like '%%') AND (ts_cgb.Sid = '1') AND (ts_cgb.CatalogId != '-1') ORDER BY "ts_cgb"."Id" ASC) AS inner_tbl ORDER BY "ts_cgb"."Id" DESC ) AS outer_tbl ORDER BY "ts_cgb"."Id" ASC
C SELECT * FROM (SELECT TOP 1 * FROM (SELECT TOP 11 "ts_cgb".*, "area_plan"."Name" FROM "ts_cgb"
INNER JOIN "area_plan" ON area_plan.Id = ts_cgb.PlanId WHERE (ts_cgb.Isbn like '%%') AND (ts_cgb.Sid = '1') AND (ts_cgb.CatalogId != '-1') ORDER BY "ts_cgb"."Id" ASC) AS inner_tbl ORDER BY "inner_tbl"."Id" DESC ) AS outer_tbl ORDER BY "outer_tbl"."Id" ASC
C 为修改后 正确处理SQL 效果。
相关文章推荐
- zend db 多表查询 LIMIT BUG 解决方法
- [Bug]使用ST_Geometry查询结果不准确的解决方法
- Hibernate通过SQL查询常量时只返回第一个字符解决方法
- 给查询出的SQL记录添加序号列,解决方法有以下两种
- Navicat查询结果不能修改的原因及解决方法
- MyBatis中使用bind标签构造模糊查询失败的解决方法
- 关于SqlServer多表根据字段值模糊匹配来连接查询的解决方法
- android开发 app闪退后fragment重叠bug解决方法,推荐使用第二种方法,完美解决问题
- PDO 查询mysql返回字段整型变为String型解决方法
- 【MarketAnalysis总结】8.0项目中遇到的一些典型的bug及其解决方法
- oracle 查询表数据慢,暂时解决方法
- java.lang.OutOfMemoryError: GC overhead limit exceeded ECLIPSE解决方法
- SWFupload在IE9中选择文件按钮无法点击bug解决方法
- mysql in子查询执行效率慢的解决方法
- jquery.ui.dialog 1.81在IE8中出现滚动条bug解决方法
- mysql limit查询优化方法(offset偏移量)
- 最常用的10种CSS BUG解决方法与技巧-浏览器兼容教程
- hql不能使用Limit的解决方法
- iOS11 下载之断点续传的bug的解决方法
- 细数IE6的一串串的恼人bug,附加解决方法!