Я должен выполнить запрос SELECT для базы данных PostgreSQL, используя OVER()
оконная функция.
Это позволяет получить диапазон выбранных строк, указанных через OFFSET
а также LIMIT
значения или общее количество строк, которое запрос получит без ограничения:
SELECT
DISTINCT *, COUNT(id) OVER() AS results_num
FROM (
SELECT id, name, surname
FROM users
WHERE children > 1
ORDER BY id
) AS x
OFFSET 0 ROWS FETCH NEXT 10 ROWS ONLY;
Для разработки метода подкачки мне нужно установить смещение а также предел динамически, поэтому, используя PDO, я определяю заполнители параметров строки запроса для OFFSET
а также LIMIT
переменные, которые затем связаны через bindParam()
:
$sql = "SELECT DISTINCT *, COUNT(id) OVER() AS results_num FROM (
SELECT id, name, surname
FROM users
WHERE children > 1
ORDER BY id
) AS x
OFFSET :offset ROWS FETCH NEXT :limit ROWS ONLY;"
$query = $dbh->prepare($sql);
$query->bindParam(':offset', $offset, \PDO::PARAM_INT);
$query->bindParam(':limit', $limit, \PDO::PARAM_INT);
$result = $query->execute();
Ошибка обнаружена:
ERROR: syntax error at or near "$2"LINE 7: ) AS x OFFSET $1 ROWS FETCH NEXT $2 ROWS ONLY;
^
Код ошибки SQL: 42601 (errorInfo
возвращается SQLSTATE[42601]: Syntax error: 7
), но это кажется очень общим, под этим кодом я обнаружил много разных синтаксических ошибок.
Это не из-за названных заполнителей; В действительности то же самое происходит с использованием заполнителей вопросительного знака:
$sql = "SELECT DISTINCT *, COUNT(id) OVER() AS results_num FROM (
SELECT id, name, surname
FROM users
WHERE children > 1
ORDER BY id
) AS x
OFFSET ? ROWS FETCH NEXT ? ROWS ONLY;"
$query = $dbh->prepare($sql);
$result = $query->execute([$offset, $limit]);
Я знаю, что PDO также пытается проверить структуру запроса, поэтому нельзя ли связывать этот тип синтаксиса с PDO?
РЕДАКТИРОВАТЬ:
Сам запрос правильно сформирован и работает; насколько я сейчас использую динамический состав строки запроса, чтобы установить смещение а также предел, очевидно, после правильной проверки их стоимости:
$sql = "SELECT DISTINCT *, COUNT(id) OVER() AS results_num FROM (
SELECT id, name, surname
FROM users
WHERE children > 1
ORDER BY id
) AS x
OFFSET " . $offset . " ROWS FETCH NEXT " . $limit . " ROWS ONLY;"
Задача ещё не решена.
Других решений пока нет …