一个事务中有多个 CREATE TABLE 错误 - 没有 PDO 异常

Posted

技术标签:

【中文标题】一个事务中有多个 CREATE TABLE 错误 - 没有 PDO 异常【英文标题】:Multiple CREATE TABLE with errors within one transaction - no PDO exception 【发布时间】:2012-03-22 21:43:55 【问题描述】:

我正在尝试在一个 PDO 事务中创建四个表。

当语句的第一个“CREATE TABLE ...”部分包含错误时,我成功获得异常、错误消息和回滚。但是当第一个“CREATE TABLE ...”部分正确编写时(如下例所示),我没有任何异常,提交,并且只创建了第一个表。

代码如下:

$conn = Connection::getInstance();

$conn->dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

$conn->dbh->beginTransaction();

$stmt = $conn->dbh->prepare("
CREATE TABLE IF NOT EXISTS `1st table` (valid SQL-code)
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8;

CREATE  TABLE IF NOT EXISTS `2nd table` (SQL-code with an error)
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8;

CREATE  TABLE IF NOT EXISTS `3rd table`...
CREATE  TABLE IF NOT EXISTS `4th table`...
");
try

    $stmt->execute();
    $conn->dbh->commit();

catch (Exception $e)

    $conn->dbh->rollBack();
    echo $e->getMessage();


unset($stmt);

经过一番研究,我在 php.net 上发现了以下note:

当在事务中发出数据库定义语言 (DDL) 语句(例如 DROP TABLE 或 CREATE TABLE)时,包括 mysql 在内的某些数据库会自动发出隐式 COMMIT。

是什么原因造成的问题以及如何解决?

【问题讨论】:

不连续单独执行语句有什么原因吗?我从未见过像这样在一个调用中运行多个语句。 我想在一个事务中创建所有表。如果 SQL 代码中有错误,我不希望创建任何错误。 允许一次调用执行多个PDO语句。如果 SQL 代码中没有错误,则所有四个表都已成功创建。 dev.mysql.com/doc/refman/5.0/en/implicit-commit.html 有你的答案。如果您希望创建所有表或不创建所有表,则必须在出错时删除已创建的表。 hmmm,我一口气创建了一堆表,我发现的问题是当sql PDO中有错误时不会返回false或抛出任何类型的错误,此外,errorInfo() & errorCode() 不会填充错误信息。然而,如果您单独执行 create table 语句并且出现 sql 错误,则 PDE 将返回 false 并使用错误信息填充 errorInfo() 和 errorCode()。这一定是一个错误? 【参考方案1】:

就像几位评论者建议的那样,事务语义不适用于 mySQL 中的数据定义语言语句 (DDL)。

PDO 实现者显然没有尝试在 DBMS 不支持的情况下添加某种客户端事务语义。

【讨论】:

以上是关于一个事务中有多个 CREATE TABLE 错误 - 没有 PDO 异常的主要内容,如果未能解决你的问题,请参考以下文章

CREATE TABLE 语句中的语法错误

MySQL 函数 Create Table 给了我一个语法错误

SQL Server 中“CREATE TABLE table AS”中的“分发选项”错误

是否可以回滚主要 SQL 数据库中的 CREATE TABLE 和 ALTER TABLE 语句?

错误:使用 rs_create_table 时未找到 AWS 会话令牌

Proc sql VALIDATE 与 CREATE TABLE