UNIONを使ったSELECT文で、プレースホルダーを使用すると、syntaxエラーになってしまいます。

投稿者: user7165

UNIONを使ったSELECT文で、プレースホルダーを使用すると、syntaxエラーになってしまいます。

プレースホルダーを使わない、以下のコードではエラーがでません。

  function getContents($page)
  {
    $limit = 3;
    $offset = $limit * $page - $limit;

    $sql = "(SELECT * FROM casper LIMIT 3 OFFSET 0) UNION ALL
            (SELECT * FROM gasper LIMIT 3 OFFSET 0) UNION ALL
            (SELECT * FROM jasper LIMIT 3 OFFSET 0) UNION ALL
            (SELECT * FROM masper LIMIT 3 OFFSET 0) UNION ALL
            (SELECT * FROM rasper LIMIT 3 OFFSET 0)
            ORDER BY title ASC";

    $stmt = $this->dbh->prepare($sql);

    $stmt->execute();

    return $stmt->fetchAll();
  }

しかし、以下のコードはエラーになります。

  function getContents($page)
  {
    $limit = 3;
    $offset = $limit * $page - $limit;

    $sql = "(SELECT * FROM casper LIMIT :limit OFFSET :offset) UNION ALL
            (SELECT * FROM gasper LIMIT :limit OFFSET :offset) UNION ALL
            (SELECT * FROM jasper LIMIT :limit OFFSET :offset) UNION ALL
            (SELECT * FROM masper LIMIT :limit OFFSET :offset) UNION ALL
            (SELECT * FROM rasper LIMIT :limit OFFSET :offset)
            ORDER BY title ASC";

       $stmt = $this->dbh->prepare($sql);

    $stmt->bindValue(':limit', $limit, PDO::PARAM_INT);
    $stmt->bindValue(':offset', $offset, PDO::PARAM_INT);
    $stmt->execute();

    return $stmt->fetchAll();
  }

エラー内容は以下です。

Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''3' OFFSET '0') UNION ALL
            (SELECT * FROM jasper LIMIT '3' OFFSET '0' at line 2' in /var/www/html/class/Jk.php:51
Stack trace:
#0 /var/www/html/class/Jk.php(51): PDOStatement->execute()
#1 /var/www/html/index.php(5): Jk->getVideos(1)
#2 {main}
  thrown in /var/www/html/class/Jk.php on line 51

プレースホルダーを使っても、結果的にはプレースホルダーを使わず、値を直接している方法と同じになるはずだと思うのですが、なぜエラーになるのでしょうか?

環境に以下になります。

CentOS 6.6
PHP 5.3.3
MySQL 5.1.73

よろしくお願いします。

解決

エラーになるのはメッセージにある実SQLの

SELECT * FROM jasper LIMIT ‘3’ OFFSET ‘0’

に含まれるLIMITおよびOFFSETでの文字列型からの暗黙変換が許可されていないからです。

なのでheliac2001さんの言うようにintval($limit)とか(int)$limitで明示的に変換すれば数値扱いになるかもしれません。

回答者: Anonymous

Leave a Reply

Your email address will not be published. Required fields are marked *