Yii2预处理语句无法评估包含在引号中的参数

时间:2017-10-24 05:46:02

标签: postgresql pdo yii2 postgis

$params = [
    ':x1' => $locationBox['leftLongitude'],
    ':y1' => $locationBox['topLatitude'],
    ':x2' => $locationBox['rightLongitude'],
    ':y2' => $locationBox['topLatitude'],
    ':x3' => $locationBox['rightLongitude'],
    ':y3' => $locationBox['bottomLatitude'],
    ':x4' => $locationBox['leftLongitude'],
    ':y4' => $locationBox['bottomLatitude'],
    ':x5' => $locationBox['leftLongitude'],
    ':y5' => $locationBox['topLatitude']
];

$sql = "
    ....
    INNER JOIN tag_geo T3 ON (T3.id = T2.tag_id_b AND ST_Covers(ST_GeogFromText('POLYGON((:x1 :y1, :x2 :y2, :x3 :y3, :x4 :y4, :x5 :y5))'), T3.geo_location));
";

$connection = \Yii::$app->getDb();
$command = $connection->createCommand($sql);
$command->bindValues($params);
$result = $command->queryAll();

我收到错误:
SQLSTATE [HY093]:参数号无效:: x1无法准备SQL

注意单一刻度('POLYGON),如果我删除包裹POLYGON函数的刻度,则参数得到评估但发生了另一个错误,因为此POLYGON必须是单引号。

1 个答案:

答案 0 :(得分:1)

由于POLYGON函数周围有单引号,因此db引擎可以识别多边形部分,例如,作为字符串POLYGON((:x1 :y1, :x2 :y2, :x3 :y3, :x4 :y4, :x5 :y5))。所以你应该在sql语句中只实现一个标记(:polygon)istead:

<?php

$sql = "
    ....
    INNER JOIN tag_geo T3 ON (T3.id = T2.tag_id_b AND ST_Covers(ST_GeogFromText(:polygon), T3.geo_location));
";

$params = [
    ":poligon" => sprintf( // Output: POLYGON((x1-value y1-value, x2-value y2-value, ...))
            "POLYGON((%s %s, %s %s, %s %s, %s %s, %s %s))"
            , $locationBox['leftLongitude']
            , $locationBox['topLatitude']
            , $locationBox['rightLongitude']
            , $locationBox['topLatitude']
            , $locationBox['rightLongitude']
            , $locationBox['bottomLatitude']
            , $locationBox['leftLongitude']
            , $locationBox['bottomLatitude']
            , $locationBox['leftLongitude']
            , $locationBox['topLatitude']
    )
];

//...

当然,如果它仍然无效,请使用问号标记(?)。

这种情况类似于尝试准备使用LIKE关键字的sql语句的情况。这里有一个例子:Syntax of LIKE in PreparedStatement