- Модуль: main
- Путь к файлу: ~/bitrix/modules/main/lib/db/mssqlsqlhelper.php
- Класс: BitrixMainDBMssqlSqlHelper
- Вызов: MssqlSqlHelper::getTopSql
public function getTopSql($sql, $limit, $offset = 0)
{
$offset = intval($offset);
$limit = intval($limit);
if ($offset > 0 && $limit <= 0)
throw new MainArgumentException("Limit must be set if offset is set");
if ($limit > 0)
{
if ($offset <= 0)
{
$sql = preg_replace("/^\s*SELECT/i", "SELECT TOP ".$limit, $sql);
}
else
{
$orderBy = '';
$sqlTmp = $sql;
preg_match_all("#\sorder\s+by\s#i", $sql, $matches, PREG_OFFSET_CAPTURE);
if (isset($matches[0]) && is_array($matches[0]) && !empty($matches[0]))
{
$idx = $matches[0][count($matches[0]) - 1][1];
$s = mb_substr($sql, $idx);
if (substr_count($s, '(') === substr_count($s, ')'))
{
$orderBy = $s;
$sqlTmp = mb_substr($sql, 0, $idx);
}
}
if ($orderBy === '')
{
$orderBy = "ORDER BY (SELECT 1)";
$sqlTmp = $sql;
}
// ROW_NUMBER() Returns the sequential number of a row within a partition of a result set, starting at 1 for the first row in each partition.
$sqlTmp = preg_replace(
"/^\s*SELECT/i",
"SELECT ROW_NUMBER() OVER (".$orderBy.") AS ROW_NUMBER_ALIAS,",
$sqlTmp
);
$sql =
"WITH ROW_NUMBER_QUERY_ALIAS AS (".$sqlTmp.") ".
"SELECT * ".
"FROM ROW_NUMBER_QUERY_ALIAS ".
"WHERE ROW_NUMBER_ALIAS BETWEEN ".($offset + 1)." AND ".($offset + $limit);
}
}
return $sql;
}