代码之家  ›  专栏  ›  技术社区  ›  Polsonby

使用SQL脚本和事务管理MySQL架构更改

  •  1
  • Polsonby  · 技术社区  · 14 年前

    我在一个php/mysql应用程序中处理多个数据库。我有开发、测试、分段和生产数据库来保持同步。

    目前,我们仍在构建这个东西,所以很容易保持它们的同步。我使用我的dev-db作为主数据库,当我想更新其他数据库时,我只需对它们进行核攻击,然后从我的数据库中重新创建它们。但是,将来一旦有了真实的数据,我就不能这样做了。

    我想将SQL脚本作为文本文件编写,我可以使用SVN中随附的PHP更改进行版本转换,然后在更新它们时将这些脚本应用到每个DB实例。

    我希望使用事务,以便在脚本期间出现任何错误时,它将回滚所做的任何部分更改。所有表都是innodb

    当我尝试添加一个已经存在的列,并添加一个这样的新列时:

    SET FOREIGN_KEY_CHECKS = 0;
    START TRANSACTION;
    ALTER TABLE `projects` ADD COLUMN `foo1` varchar(255) NOT NULL after `address2`;
    ALTER TABLE `projects` ADD COLUMN `foo2` varchar(255) NOT NULL after `address2`;
    COMMIT;
    SET FOREIGN_KEY_CHECKS = 1;
    

    …当然,它仍然提交新的列,尽管它未能添加第一个列,因为我发出了commit而不是rollback。

    我需要它在出错时有条件地发出rollback命令。如何在临时SQL脚本中执行此操作?

    我知道存储过程的“声明退出处理程序”功能,但我不想存储它;我只想将其作为一个特殊脚本运行。

    为了获得条件回滚,我是否需要将其转换为存储过程,或者是否有其他方法可以在单个临时SQL脚本中使整个事务成为原子性的?

    欢迎使用示例的任何链接-我在谷歌上搜索过,但到目前为止只找到存储过程示例

    多谢

    伊恩

    编辑-这永远都不起作用;当遇到以下情况时,alter table会导致隐式提交: http://dev.mysql.com/doc/refman/5.0/en/implicit-commit.html 感谢布莱恩的提醒

    1 回复  |  直到 14 年前
        1
  •  2
  •   Brian Hooper    14 年前

    前几天我了解到,在MySQL中,数据定义语言语句总是起作用,并在应用时导致事务被提交。我想如果你想确保成功的话,你可能需要以互动的方式来做这件事。

    我在这个讨论这个问题的网站上找不到这个问题(只是几天前)。

    如果需要保持多个数据库同步,可以研究复制。尽管复制不需要小题大做,但它可能是您所需要的。见 http://dev.mysql.com/doc/refman/5.0/en/replication-features.html