15

アプリケーションで PDO を使用しています。しかし、を含むクエリで準備済みステートメントを使用しているときに問題が発生しましたLIMIT。どうしたの?
コード:

$start = 0;
$rows = 20;
$sql = "SELECT * FROM tbl_news ORDER BY date DESC LIMIT ?, ?";
$q = $db->prepare($sql);
$q->execute(array($start , $rows));

エラー:

「0」、「20」付近で使用する正しい構文については、MySQL サーバーのバージョンに対応するマニュアルを確認してください。

4

5 に答える 5

14

MySQL にプリペアド ステートメントを使用して LIMIT キーワードを投稿することに関しては、以下のコードで問題を解決できます。

$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, FALSE);

Álvaro G. VicarioMaerlynに感謝

于 2012-07-31T11:04:10.653 に答える
13

次のようにできます。

$sql = SELECT * FROM tbl_news ORDER BY date DESC LIMIT :start, :rows";
$q = $db->prepare($sql);
$q->bindParam(':start', $start, PDO::PARAM_INT);
$q->bindParam(':rows',$rows, PDO::PARAM_INT);
于 2012-07-31T11:00:57.450 に答える
3

これは5.5.6 でメモリから修正された既知のバグです。

記事から: LIMIT は、どのコンテキストでも変数を許可しません。その引数は整数定数でなければなりません。

さらに編集: (この問題には競合があります) ユーザー変数は準備済みステートメントの LIMIT 句の引数として受け入れられ、準備済みステートメントの SQL 構文はストアド プロシージャで使用できます。

3番目の編集:このリンクは、これらが準備済みステートメントで機能することを説明しています。

于 2012-07-31T10:55:20.840 に答える
1

私はちょうど同じ問題に出くわしました。私にとっては、独自のステートメントクラス(拡張PDOStatement)を独自のexecute()メソッドで使用すると修正されました。

これはクラスです:

class MyPDOStatement extends PDOStatement {

  public function execute($input_parameters = null) {
    if (is_array($input_parameters)) {
      $i = 1;
      foreach ($input_parameters as $p) {
        // default to string datatype
        $parameterType = PDO::PARAM_STR;
        // now let's see if there is something more appropriate
        if (is_bool($p)) {
          $parameterType = PDO::PARAM_BOOL;
        } elseif (is_null($p)) {
          $parameterType = PDO::PARAM_NULL;
        } elseif (is_int($p)) {
          $parameterType = PDO::PARAM_INT;
        }
        // parameters passed to execute() are input-only parameters, so use
        // bindValue()
        $this->bindValue($i, $p, $parameterType);
        $i++;
      }
    }
    return parent::execute();
  }

}

PDO にデフォルトのステートメント クラスの代わりにこのステートメント クラスを使用するように指示するには、次のようにします。

$db = new PDO(...);
$db->setAttribute(PDO::ATTR_STATEMENT_CLASS, array('MyPDOStatement'));

問題のコードが機能するようになりました。

$start = 0;
$rows = 20;
$sql = "SELECT * FROM tbl_news ORDER BY date DESC LIMIT ?, ?";
$q = $db->prepare($sql);
$q->execute(array($start , $rows));

確実にする必要があるのは、ステートメントにバインドされた変数が正しい型である整数であることだけです。配列などの数値文字列がある場合は、次の$_GETようにすることができます。

if (isset($_GET['start']) && is_numeric($_GET['start'])
    && is_int($_GET['start'] + 0) {
  $start = (int) $_GET['start'];
}

最後にもっと簡単な方法があるかどうかはわかりませんが、少なくとも私にとってはうまくいきます。

于 2013-03-03T19:18:12.583 に答える
-3

dateあなたがそれをラップしなければならない予約語です back-ticks

于 2012-07-31T10:54:22.910 に答える