4

我正在为用 PHP 编写的 Web 应用程序开发更新系统。在更新过程中,我可能需要执行一堆 MySQL 脚本。

运行脚本的基本过程是:

  1. 搜索 Mysql 脚本
  2. 开始交易
  3. 使用 mysqli_multi_query 执行每个脚本,因为一个脚本可以包含多个查询
  4. 如果一切顺利,则提交事务,否则回滚。

我的代码看起来像:

$link = mysqli_connect(...);

mysqli_autocommit($link, false);

// open dir and search for scripts in file.
// $file is an array with all the scripts
foreach ($scripts as $file) {

    $script = trim(file_get_contents($scriptname));

    if (mysqli_multi_query($link, $script)) {
        while (mysqli_next_result($link)) {
            if ($resSet = mysqli_store_result($link)) { mysqli_free_result($resSet); }

            if (mysqli_more_results($link)) { }
        }
    }

    // check for errors in any query of any script
    if (mysqli_error($link)) {
        mysqli_rollback($link);
        return;
    }
}
mysqli_commit($link);

以下是脚本示例(用于演示目的):

script.1.5.0.0.sql:
update `demo` set `alias` = 'test1' where `id` = 1;
update `users` set `alias` = 'user1' where `id` = 1;

script 1.5.1.0.sql: 
insert into `users`(id, key, username) values(3, '100', 'column key does not exist');
insert into `users`(id, key, username) values(3, '1', 'column key exists');

在这种情况下,脚本 1.5.0.0 将在没有错误的情况下执行,而脚本 1.5.1.0 将生成错误(出于演示目的,假设该列key是唯一的,并且已经有一行key= 1)。

在这种情况下,我想回滚每个已执行的查询。但是发生的情况是 1.5.1.0 的第一个插入不在数据库中(正确),但来自 1.5.0.0 的更新已成功执行。

评论:

  1. 我的第一个选择是用“;”从每个脚本中拆分每个查询 并独立执行查询。这不是一个选项,因为我必须能够将 HTML 代码插入数据库(例如:如果我想插入类似“ ”的内容)
  2. 我已经搜索过 StackOverflow 和 google 并遇到了类似这样的解决方案,但我更喜欢使用 mysqli_multi_query 之类的解决方案,而不是使用函数来拆分每个查询。对于调试目的,它更容易理解和更容易
  3. 我还没有测试过,但我相信我可以合并所有脚本并只执行一个查询。但是,一次执行一个脚本会很有用,这样我就可以找出哪个脚本有错误。
  4. 表引擎是 InnoDB。

感谢您是否可以指出一些方法来完成这项工作。

4

2 回答 2

2

编辑:仅在第一个查询失败mysqli_multi_query()时才返回 false 。如果第一个查询没有失败,那么您的代码将运行,如果成功,则为空。您需要在每个可能成功或失败的 mysqli 函数之后检查错误。mysql_store_result()mysqli_error()

于 2011-08-26T04:07:36.017 回答
0

好的,在又花了一天调试之后,我发现了问题所在。

实际上,它与代码本身或 mysqli 函数无关。我习惯了支持 DDL 语句的 MS SQL 事务。MySQL 不支持 DDL 语句并隐式提交数据(隐式提交)。我在自动提交数据的脚本之一中有一个 DROP 表。

于 2014-05-05T11:08:33.770 回答