一个事务中有多个 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 异常的主要内容,如果未能解决你的问题,请参考以下文章
MySQL 函数 Create Table 给了我一个语法错误
SQL Server 中“CREATE TABLE table AS”中的“分发选项”错误
是否可以回滚主要 SQL 数据库中的 CREATE TABLE 和 ALTER TABLE 语句?