繁体   English   中英

如何在pg_prepare()pg_execute()中使用参数ORDER BY?

[英]How to use parametric ORDER BY with pg_prepare() pg_execute()?

我想根据用户决定的顺序对这个查询进行排序,因此已将其参数化。 我真的不明白为什么第二个参数被忽略了! (它不对结果进行排序)

function getY($id, $order){
    ....
    ....
    $db = connection_pgsql() or die ('connection failed');
    $sql = "SELECT id, y FROM test WHERE id = $1 ORDER BY $2";
    $resource = pg_prepare($db, "get_y", $sql);

    $value = array($id, $order);
    $resource = pg_execute($db, "get_y", $value);
    ....
    ....
}

如果我这样通过:

$sql = "SELECT id, y FROM test WHERE id = $1 ORDER BY {$order}";

它可以工作,但我认为这并不安全(不是吗?)。

我只发现了PDO :: execute的pgsql 42601错误,这确实不能解决我的问题。

ORDER BY $ 2正在对固定值进行排序,如下所示:

SELECT * FROM t1 ORDER BY 'some string';

由于所有记录将按相同的字符串排序,因此没有排序...。

ORDER BY也是无法准备的事情,因为在准备过程中您不会告诉数据库要用于排序的列。 这就像计划一次公路旅行,但不知道要去哪里。

要解决此问题,您需要动态SQL和其他一些安全措施:

function getY($id, $order){
    ....
    ....
    $db = connection_pgsql() or die ('connection failed');

    $sql = "SELECT quote_ident($1);"; // give me a secure object name

    $resource = pg_query_params($db, $sql, array($order)); // error handling is missing

    $order = pg_fetch_result($resource, 0, 0);

    $sql = "SELECT id, y FROM test WHERE id = $1 
        ORDER BY ".$order.";"; // <===== it's now safe to use

    $resource = pg_prepare($db, "get_y", $sql); // error handling is missing

    $value = array($id);
    $resource = pg_execute($db, "get_y", $value); // error handling is missing
    ....
    ....
}

现在,您将创建一个完整的SQL字符串,由于quote_ident()可以准备并保存该字符串。 无论$ order中包含什么内容,它将在PostgreSQL中被视为标识符。 在这种情况下就像一列。 如果缺少该列,则准备将失败。 这就是为什么您需要适当的错误处理的原因,您知道有一天该查询将由于输入错误而失败。

如果仅使用此语句一次,则也可以使用pg_query_params()代替pg_prepare()+ pg_execute()。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM