PDO在pgsql和mysql中准备的语句

时间:2019-03-13 14:37:44

标签: php mysql postgresql pdo

我想知道为什么PDO驱动程序pgsqlmysql在关于准备好的语句(PDO::ATTR_EMULATE_PREPARES => false)上会有不同的行为。

为演示我的意思,我准备了两个等效的查询(一个用于pgsql,一个用于mysql)和一个PHP单元测试用例。

以下查询(原本表 不存在)将产生以下错误:


pgsql

INSERT INTO "addresss" SELECT * FROM "address" WHERE "id" = 80

SQLSTATE[42P01]: Undefined table: 7 FEHLER: Relation »addresss« existiert nicht


mysql

INSERT INTO `addresss` SELECT * FROM `address` WHERE `id` = 80

SQLSTATE[42S02]: Base table or view not found: 1146 Table 'addresss' doesn't exist


这是测试用例:

try
{
    $stmt = self::$connection->getPdo()->prepare($sql);
    $stmt->execute();
}
catch (\PDOException $exception){
    echo $exception->getMessage();
}

mysql的情况下,已经在getPdo()->prepare($sql)上引发了异常,但是在pgsql的情况下,仅在$stmt->execute()上引发了异常。

为什么我知道呢?因为,当我省略$stmt->execute()并为pgsql运行测试用例时,测试成功。但是对于mysql,它仍然失败。

  • 那是为什么?
  • PDO::ATTR_EMULATE_PREPARES => false是否不能像pgsql那样对mysql起作用?因为当我将其设置为true时,突然出现了mysql的相同行为,即该异常仅在执行时抛出,而不是在准备时抛出。
  • 我可以以某种方式强制使用PDO像使用pgsql一样在使用mysql准备语句时引发错误吗?

1 个答案:

答案 0 :(得分:1)

看看PDO pgsql驱动程序的source代码,它似乎将准备工作推迟到源中按注释执行的第一次执行:

/* we deferred the prepare until now, because we didn't  
 * know anything about the parameter types; now we do */