1

だから私はいくつかのコードを持っています

//passed as function param
$clause[2] = "'2016-09-09' AND '2016-09-09'"

$sql = "SELECT {$columns} FROM `{$table}` WHERE `{$clause[0]}` {$clause[1]} :clause";
$stm = $this->db->prepare($sql);
$stm->bindValue("clause", $clause[2]);
if ($stm->execute()) {
   return $stm->fetchAll(PDO::FETCH_OBJ);
}
d
//echo'd $sql
SELECT * FROM `deliveries` WHERE `delivery-date` BETWEEN :clause

:clausein$sqlを生の入力に置き換えると、正常に'2016-09-09' AND '2016-09-09'動作します。:clause または a を使用してバインドしようとするとすぐ?に失敗します。どうすればいいのかわかりません:(助けてくれてありがとう!

4

1 に答える 1

2

そのような式全体をバインドすることはできません。値のバインドは単なる文字列置換ではありません。通常は単一のスカラー値を配置する場所にのみ、SQL クエリの値をバインドできます。たとえば、BETWEEN述語に 2 つの値が必要な場合は、2 つのプレースホルダーが必要です。

さらに、バインドされた値に引用符を入れてはなりません。プレースホルダーが正確に 1 つのスカラー値を意味するという事実により、引用符は不要になります。

汎用関数を作成しようとしているように見えるので、必要な条件を作成できます。$clause配列には、列、演算子、および値が含まれているはずです。

IN()またはのような複数値の述語については、SQL を別の形式にフォーマットするコードを記述する必要がありますBETWEEN

$column = $clause[0];
$operator = $clause[1];
$valuesArray = (array) $clause[2];
switch ($operator) {
case 'IN':
    $expression = "(" . implode(",", array_fill(1, count($valuesArray), "?") . ")";
    break;
case 'BETWEEN':
    $expression = "? AND ?";
    break;
default:
    $expression = "?";
}
$sql = "SELECT {$columns} FROM `{$table}` WHERE `{$column}` {$operator} {$expression}";
$stm = $this->db->prepare($sql);
$stm->execute($valuesArray);
return $stm->fetchAll(PDO::FETCH_OBJ);

を有効にするだけなので、 execute() の戻り値をテストする必要はありませんPDO::ERRMODE_EXCEPTION

于 2016-09-09T22:13:34.167 に答える