dongnanman9093 2015-01-12 19:05
浏览 249
已采纳

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

I want to order this query by something decided by the user so I've made it parameterized. I really can't understand why the second parameter is being ignored! (It doesn't order the results)

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);
    ....
    ....
}

If I pass it like this:

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

it works but I think it's not safe (isn't it?).

I've only found this pgsql 42601 error with PDO::execute which really doesn't solve my problem.

  • 写回答

1条回答 默认 最新

  • dongliangkeng1056 2015-01-13 07:37
    关注

    ORDER BY $2 is sorting a fix value, something like this:

    SELECT * FROM t1 ORDER BY 'some string';
    

    As all records will be sorted by the same string, there is no sorting....

    ORDER BY is also something that can't be prepared because you don't tell the database during preparation what column you want to use for the sorting. It's like planning a road trip but without knowing where to go.

    To fix this, you need dynamic SQL and some other security measures:

    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
        ....
        ....
    }
    

    You now create a complete string of SQL that can be prepared and is save because of quote_ident(). Whatever content there will be in $order, it will be treated as an identifier in PostgreSQL. Like a column in this case. If that column is missing, the prepare will fail. That's why you need proper error handling, you know that one day this query will fail because of bad input.

    If you're using this statement just once, you could also use pg_query_params() instead of pg_prepare() + pg_execute().

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 虚幻5 UE美术毛发渲染
  • ¥15 CVRP 图论 物流运输优化
  • ¥15 Tableau online 嵌入ppt失败
  • ¥100 支付宝网页转账系统不识别账号
  • ¥15 基于单片机的靶位控制系统
  • ¥15 真我手机蓝牙传输进度消息被关闭了,怎么打开?(关键词-消息通知)
  • ¥15 装 pytorch 的时候出了好多问题,遇到这种情况怎么处理?
  • ¥20 IOS游览器某宝手机网页版自动立即购买JavaScript脚本
  • ¥15 手机接入宽带网线,如何释放宽带全部速度
  • ¥30 关于#r语言#的问题:如何对R语言中mfgarch包中构建的garch-midas模型进行样本内长期波动率预测和样本外长期波动率预测