Welcome Guest, Not a member yet? Register   Sign In
MSSQL Limit - A working "Fix" .
#10

[eluser]Unknown[/eluser]
Hey Gang Thanks for this thread.

I made a few mods to the function above by Kyle to accommodate the following:

1. No OrderBy column name in the select query
2. No specific ColumnName in the Select Query, i.e. a wildcard 'Select *'

This should basically let you browse rows with a statement like the following:

Code:
// Active Record Query
$this->db->limit($limit, $offset);
$query = $this->db->get($table);

Where the limit and offset can be set without an accompanying orderBy statement. Its kinda hacky so feel free sure modify or disregard.

Code:
/**
* Limit string
*
* Generates a platform-specific LIMIT clause
*
* @access public
* @param string the sql query string
* @param integer the number of rows to limit the query to
* @param integer the offset value
* @return string
*/

/* ORIGINAL FUNCTION COMMENTED OUT
function _limit($sql, $limit, $offset)
{
$i = $limit + $offset;
return preg_replace('/(^\SELECT (DISTINCT)?)/i','\\1 TOP '.$i.' ', $sql);
}
*/

// Modified as per this thread: http://ellislab.com/forums/viewthread/160626/

protected function _limit($sql, $limit, $offset)
{
if($offset === FALSE)
{
  // Do simple limit if no offset
  $i = $limit + $offset;
  return preg_replace('/(^\SELECT (DISTINCT)?)/i','\\1 TOP '.$i.' ', $sql);
}
else
{
  if(!$this->ar_orderby)
  {
   // We do not have an orderBy column set and do not have the tableName
   // here, so grab the table name from the $sql statement by regex and
   // then grab the first column of the tableName in the $sql statement
   // from the schema and let that be the orderBy column. Phew.
   $match_pattern = '/(.*FROM )/s';
   $match_replacement = '';
   $table = preg_replace($match_pattern, $match_replacement, $sql);
   $orderBy  = "ORDER BY (SELECT [COLUMN_NAME] FROM [information_schema].[columns] WHERE [TABLE_NAME] = '".$table."' AND [ORDINAL_POSITION] = 1)";
  }
  else
  {
   $orderBy  = "ORDER BY ";
   $orderBy .= implode(', ', $this->ar_orderby);
  }
  if ($this->ar_order !== FALSE)
  {
   $orderBy .= ($this->ar_order == 'desc') ? ' DESC' : ' ASC';
  }
  $sql = preg_replace('/(\\'. $orderBy .'\n?)/i','', $sql);
  $sql = preg_replace('/(^\SELECT (DISTINCT)?)/i','\\1 row_number() OVER ('.$orderBy.') AS CI_offset_row_number, ', $sql);

  if(!$this->ar_orderby)
  {
   // No ColumnName so do a wildcard  
   $columns = '*';
  }
  else
  {
   $columns = implode(',',$this->ar_select);
  }
  $newSQL = "SELECT " . $columns . " \nFROM (\n" . $sql . ") AS A \nWHERE A.CI_offset_row_number BETWEEN (" .($offset + 1) . ") AND (".($offset + $limit).")";
  return $newSQL;
}
}
// --------------------------------------------------------------------

Haven't tested this in production yet but is working for me at the moment.

Thanks again for the thread.


Messages In This Thread
MSSQL Limit - A working "Fix" . - by El Forum - 07-13-2010, 08:03 AM
MSSQL Limit - A working "Fix" . - by El Forum - 07-14-2010, 08:55 AM
MSSQL Limit - A working "Fix" . - by El Forum - 07-14-2010, 10:43 AM
MSSQL Limit - A working "Fix" . - by El Forum - 07-15-2010, 01:34 PM
MSSQL Limit - A working "Fix" . - by El Forum - 02-18-2011, 02:38 PM
MSSQL Limit - A working "Fix" . - by El Forum - 02-28-2011, 08:01 PM
MSSQL Limit - A working "Fix" . - by El Forum - 08-10-2011, 05:46 AM
MSSQL Limit - A working "Fix" . - by El Forum - 03-07-2012, 02:10 PM
MSSQL Limit - A working "Fix" . - by El Forum - 09-11-2012, 06:22 PM
MSSQL Limit - A working "Fix" . - by El Forum - 06-12-2013, 08:45 AM



Theme © iAndrew 2016 - Forum software by © MyBB