I have to perform a SELECT query on a PostgreSQL database usign the OVER() window function.
It allows to get either the range of selected rows specified through the OFFSET and LIMIT values, or the number of total rows the query would get without the 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;
To develop a paging method I need to set offset and limit dynamically, so, using PDO, I define the query string setting placeholders for OFFSET and LIMIT variables which are then bound through 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();
The error caught is:
ERROR: syntax error at or near "$2"
LINE 7: ) AS x OFFSET $1 ROWS FETCH NEXT $2 ROWS ONLY;
^
The SQL error code is 42601 (errorInfo returns SQLSTATE[42601]: Syntax error: 7), but it seems to be very generic, under this code I found a lot of different syntax errors.
It is not due to the named placeholders; infact the same happens by using question mark placeholders:
$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]);
I know PDO also tries to validate the query structure, so is this type of syntax not allowed to be bound by PDO?
EDIT:
The query itself is well-formed and works; as far as now I use dynamic query string composition to set offset and limit, obviously after having properly validated their value:
$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;"
$offsetand$limitvariables in the query string.