• Модуль: main
  • Путь к файлу: ~/bitrix/modules/main/lib/db/mssqldbconnection.php
  • Класс: BitrixMainDBMssqlDbConnection
  • Вызов: MssqlDbConnection::queryInternal
protected function queryInternal($sql, array $arBinds = null, $offset = 0, $limit = 0, BitrixMainDiagSqlTrackerQuery $trackerQuery = null)
{
	$this->connectInternal();

	$offset = intval($offset);
	$limit = intval($limit);

	if ($offset > 0 && $limit <= 0)
		throw new BitrixMainArgumentException("Limit should be set if offset is set");

	if ($limit > 0)
	{
		if (preg_match("#\sROW_NUMBER\s*\(\s*\)#i", $sql)
			|| preg_match("#SELECT\s+TOP\s+\d#i", $sql))
			throw new BitrixMainArgumentException("Duplicate limit settings");

		if ($offset <= 0)
		{
			$sql = preg_replace("/^\s*SELECT/i", "SELECT TOP ".$limit, $sql);
		}
		else
		{
			if (preg_match("#(\s+order\s+by(\s+[a-z0-9_.]+(\s+(asc|desc))?\s*,)*(\s+[a-z0-9_.]+(\s+(asc|desc))?)\s*)$#i", $sql, $matches))
			{
				$orderBy = $matches[1];
				$sqlTmp = substr($sql, 0, -strlen($orderBy));
			}
			else
			{
				$orderBy = "ORDER BY (SELECT 1)";
				$sqlTmp = $sql;
			}

			$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." AND ".($offset + $limit - 1)."";
		}
	}

	if ($trackerQuery != null)
		$trackerQuery->startQuery($sql, $arBinds);

	$result = sqlsrv_query($this->resource, $sql, array(), array("Scrollable" => 'forward'));

	if ($trackerQuery != null)
		$trackerQuery->finishQuery();

	$this->lastQueryResult = $result;

	if (!$result)
		throw new SqlException('MS Sql query error', $this->getErrorMessage());

	return $result;
}