【问题标题】: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 '?'您的 SQL 语法有错误;检查与您的 MySQL 服务器版本相对应的手册,以了解在“?”附近使用的正确语法
【发布时间】:2015-03-30 21:07:34
【问题描述】:

当我执行这段代码时:

$db = new Database();
$statement = $db->prepare("SHOW TABLES LIKE :table");            
if(!$statement)
    throw New Exception($db->errorInfo()[2]);

foreach($tables as $table){
    $statement->execute(array(':table' => $table));
    if($statement->rowCount() == 0)
        echo 'Table ' . $table . ' doesn\'t exist';
}

我收到以下错误:

Exception: 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 '?' at line 1 in something.php on line 4

当我像这样在:table 周围加上单引号时不会引发错误:$statement = $db->prepare("SHOW TABLES LIKE ':table'"); - 但我认为您不应该在准备好的语句中将单引号放在参数周围?
另外,我将这个属性设置为数据库:$db->setAttribute(PDO::ATTR_EMULATE_PREPARES,false);,这样当查询中使用错误的语法时$statement 为假,所以我可以抛出异常。当PDO::ATTR_EMULATE_PREPARES设置为true时,可以执行查询。

我的问题是:如何在使用 PDO 准备好的语句时检查查询中的错误?为什么会出现语法错误?

【问题讨论】:

  • 带命名参数,别忘了冒号(:):$statement->execute(array(':table' => $table));
  • @MarkBaker 为什么我从来没有因为省略冒号而收到错误消息?我几乎总是忘记它
  • @blackVeiledKilljoySkellington 因为无论哪种方式都可以。您应该使用它,但 PDO 知道所有命名的占位符都以冒号开头,因此如果您省略它,它会添加它。

标签: php mysql pdo


【解决方案1】:

您需要使用PDO::ATTR_EMULATE_PREPARES 选项,因为本机准备好的语句只能在允许表达式的情况下使用占位符。 SHOW TABLES LIKE 需要文字字符串,而不是表达式,因此您不能在此处使用本机占位符。所以把它放在你的代码之前:

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

【讨论】:

  • 当查询中出现语法错误时,有没有办法仍然可以抛出异常?
  • 这不会改变语法检查。
  • PDO::ATTR_EMULATES_PREPARES 设置为true 确实解决了错误,但是当我将查询更改为一些随机的东西(例如"SHOW BANANAS BLABLABLA LIKE :table")时,不会抛出异常
  • 如果你使用PDO::ERRMODE_EXCEPTION会发生什么?
  • 差不多。请改用try/catch
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-07
  • 2012-05-02
  • 2013-07-14
  • 1970-01-01
相关资源
最近更新 更多