如何将 pdo 的预准备语句用于排序和限制子句?

2022-08-30 22:06:00

我想使用一个预准备语句,其中传入的参数用于 and 子句,如下所示:ORDER BYLIMIT

$sql = 'SELECT * FROM table ORDER BY :sort :dir LIMIT :start, :results';
$stmt = $dbh->prepare($sql);
$stmt->execute(array(
     'sort'  => $_GET['sort'], 
     'dir'  => $_GET['dir'], 
     'start'  => $_GET['start'],
     'results' => $_GET['results'],
     )
    );

但不返回任何内容。$stmt->fetchAll(PDO::FETCH_ASSOC);

有人能指出我做错了什么吗?能做到吗?如果不是,我应该参考什么来获取可以使用参数的子句的完整列表?


答案 1

使用后 :

$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

我收到消息 :

未捕获的异常“PDOException”,带有消息“SQLSTATE[42000]:语法错误或访问冲突:1064 SQL语法中存在错误;检查与您的MySQL服务器版本相对应的手册,以获取在第1行的“0”,“10”附近使用正确的语法

因此,当您使用数组执行时,它会将您的输入视为字符串,这对于LIMIT来说不是一个好主意。

$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$sql = "SELECT * FROM table ORDER BY :sort :dir LIMIT :start, :results";
$stmt = $dbh->prepare($sql);
$stmt->bindParam(':start', $_GET['start'], PDO::PARAM_INT);
$stmt->bindParam(':results', $_GET['results'], PDO::PARAM_INT);
$stmt->bindParam(':sort', $_GET['sort']);
$stmt->bindParam(':dir', $_GET['dir']);
$stmt->execute();

$data = $stmt->fetchAll(PDO::FETCH_ASSOC);
print_r($data);

答案 2

预准备语句允许 DBMS 在实际执行对所提供参数的查询之前为您的查询生成查询计划。更改 的字段需要不同的查询计划,因为以不同的方式对数据进行排序可能会极大地影响 DBMS 选择获取数据的方式:例如,某些索引在一种情况下可能会有所帮助,但在另一种情况下则不然。因此,字段应构成传递到方法中的 SQL 字符串的一部分,而不是绑定到 之前的查询。ORDER BYORDER BYprepare()execute()

至于子句,目前尚不清楚其参数是否会影响查询计划,因此这些参数可能会在以后绑定,具体取决于您的 DBMS。根据这个SO答案,它应该被允许。LIMIT


推荐