12

我正在使用 Liquibase 生成 MySQL 和 HSQLDB 数据库。
在几个表中,我有一个名为“last_modified”的列,它是该特定记录的最后一次更新的 TIMESTAMP。

<changeSet author="bob" id="7">
    <createTable tableName="myTable">
        <column autoIncrement="true" name="id" type="INT">
            <constraints nullable="false" primaryKey="true" />
        </column>
        <column name="name" type="VARCHAR(128)">
            <constraints nullable="false" />
        </column>
        <column name="description" type="VARCHAR(512)" />
        <column defaultValueBoolean="true" name="enabled" type="BIT">
            <constraints nullable="false" />
        </column>
        <column name="last_modified" type="TIMESTAMP"/>
    </createTable>
    <modifySql dbms="mysql">
        <append value=" engine innodb" />
    </modifySql>
</changeSet>

我注意到,如果我使用 MySQL,为该列生成的 SQL 是:

`last_modified` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,

虽然如果我使用 HSQLDB,在更新的情况下不会发生任何事情,但我希望 MySQL 数据库具有相同的行为,更新时的默认值等于 CURRENT_TIMESTAMP。

如何将 CURRENT_TIMESTAMP 设置为更新时的默认值?

4

3 回答 3

9

或者你可以试试这个,因为你已经modifySql添加了标签:

<column defaultValue="CURRENT_TIMESTAMP"
             name="timestamp"
             type="TIMESTAMP">
            <constraints nullable="false"/>
 </column>
<modifySql dbms="mysql">
    <regExpReplace replace="'CURRENT_TIMESTAMP'" with="CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP"/>
    <append value=" engine innodb" />
</modifySql>

Liquibase 3.1.1 不会产生您上面描述的内容。我必须按照上面给出的处理它

于 2014-05-19T07:35:31.400 回答
7

您不能使用默认值执行此操作。MySQL 行为是非标准的,其他数据库不支持。执行此操作的正确方法是使用 TRIGGER 定义为 BEFORE UPDATE 并在每次更新行时设置时间戳。

更新:从 HSQLDB 版本 2.3.4 开始支持此功能。例如:CREATE TABLE T1(ID INT, last_modified timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP NOT NULL)。注意 NOT NULL 约束必须出现在 DEFAULT 和 ON UPDATE 子句之后。

于 2013-10-10T09:48:08.820 回答
6

我们实际上将 Liquibase 用于完全相同的用例。您需要按照 fredt 的描述创建一个更新触发器。否则,您无法确定更新是否会发生在 MySQL 以外的其他数据库上。您的变更集标签将记录如下内容:

<sql splitStatements="false">
  CREATE TRIGGER update_${tableName}_trg
    BEFORE UPDATE ON ${tableName}
      FOR EACH ROW BEGIN
        SET NEW.updated_at = NOW();
      END
</sql>

另外,我对 Stack Overflow 有一个关于如何重构其中一些代码的问题,您可以在如何重构外观相似的代码并在 Liquibase 中提供参数?.

于 2013-10-30T19:30:59.943 回答