我必须在PostgreSQL数据库上执行SELECT查询,使用OVER()
window function。
它允许获取通过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;"