php - 使用多个语句时如何获取 SQL 错误

标签 php mysql pdo

我们使用 PHP >= 7.2 和 PDO 以及 MySQL 驱动程序在一个 exec() 调用中执行多个 SQL 语句。我们使用这个概念来创建由 PHP 执行的数据库迁移脚本。这些纯 SQL 脚本包含多个 SQL 语句,由我们的 PHP 框架执行,如下所示:

$conn = PDO::conn('mysql:......','user','pw');
$ret = $conn->exec('
    DROP VIEW IF EXISTS v_my_view;
    CREATE VIEW v_my_view AS SELECT id,name FROM mytable;
');
// $ret now contains 1
if ($ret === FALSE) { // some error handling }

即使对于一个 exec() 调用中的许多语句,这也能正常工作:数据库执行所有语句。

现在,如果 SQL 本身包含错误,(例如语法错误或未知列等),对 exec() 的调用返回与之前 (1) 完全相同的结果,并且 DBH::errorInfo() 返回无错误:

$conn = PDO::conn('mysql:......','user','pw');
$ret = $conn->exec('
    DROP VIEW IF EXISTS v_my_view;
    -- The following statement creates an SQL error (unknown column):
    CREATE VIEW v_my_view AS SELECT id,name_not_known FROM mytable;
');
// $ret still contains 1
var_dump($conn->errorInfo()); // Returns Error Code 0, all fine.

所以看起来 PDO::exec() 确实支持多语句,但没有实现任何错误处理/中止机制。 这似乎也是 MySQL 独有的问题:相同的机制在 PostgreSQL 数据库上运行良好。

有什么方法可以强制 PDO 在多个语句查询上“出错时停止”?

最佳答案

是的,有。它在我的 PDO 教程中有解释,在 running multiple queries 下部分。

基本上你需要暂时打开仿真模式

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

然后使用常规 query() 方法运行您的 SQL 转储。然后您将不得不遍历每个查询的结果以捕获错误。由于您的查询似乎没有返回任何数据,因此循环可以像

一样简单
do {} while ($stmt->nextRowset());

请注意,您必须为 PDO 启用异常模式,以便为错误查询获取错误异常。如果您需要查询中的一些数据,例如插入 ID,您可以在花括号内添加必要的命令。

关于php - 使用多个语句时如何获取 SQL 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57994664/

相关文章:

php - 是否存在类似反向准备语句的东西?

php - Cakephp 3 测试 : How to load records from database?

php - 如何将一栏的内容复制到另一栏?

mysql - Google Cloud SQL 无法通过 ipv6 从 mac 上的 mysqlworkbench 连接

php - 使用 PHP 和 Mysql 查找每种数据组合(不常见的一种)的统计数据

php - 为什么查询成功后日历上没有显示任何事件?

php 5.3 CLI 垃圾字符

javascript - Braintree 付款不适用于 AJAX 提交

mysql - 在同一查询中使用 WHERE IN 和 WHERE NOT IN

mysql - 在其他条件行之后查找特定条件行