我想知道为什么PDO驱动程序pgsql
和mysql
在关于准备好的语句(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
的相同行为,即该异常仅在执行时抛出,而不是在准备时抛出。pgsql
一样在使用mysql
准备语句时引发错误吗?答案 0 :(得分:1)
看看PDO pgsql驱动程序的source代码,它似乎将准备工作推迟到源中按注释执行的第一次执行:
/* we deferred the prepare until now, because we didn't
* know anything about the parameter types; now we do */