■
CakePHP 1.2.0.5422 + SQL-Server 2005 でページングをする場合、 DboMssql::renderStatement() で定義されている SQL文では常にLIMIT分のレコードを取得するため、最終ページで端数分のレコードが取得できない。そこで、DboMssqlを継承したクラス DboMssql2005 を作り、renderStatement() を上書きする。/config/database.php で 'driver' => 'mssql2005' とすると DboMssql2005 が使われる。
/app/models/datasources/dbo/dbo_mssql2005.php
<?php uses ('model' . DS . 'datasources' . DS . 'dbo' . DS . 'dbo_mssql'); class DboMssql2005 extends DboMssql { function renderStatement($data) { extract($data); if (preg_match('/offset\s+\d+/i', $limit)) { //オフセット設定が在る場合の処理 preg_match('/top\s+(\d+)\soffset\s+(\d+)/i', $limit, $ma); $start = intval($ma[2]) + 1; $end = intval($ma[1]) + intval($ma[2]); $sql = <<<EOD WITH _Orders_ AS ( SELECT ROW_NUMBER() OVER ({$order}) AS '_no_', {$fields} FROM {$table} {$alias} {$joins} {$conditions} ) SELECT * FROM _Orders_ WHERE _no_ Between {$start} AND {$end} EOD; return $sql; } else { return "SELECT {$limit} {$fields} FROM {$table} {$alias} {$joins} {$conditions} {$order}"; } } } ?>
これで、とりあえず問題ない程度には動いている。
1.2.0.6311 では renderStatement() の引数が増えているので若干ソースを直す必要があるはず。