默认值ON UPDATE Liquibase

时间:2013-10-07 16:57:00

标签: mysql sql database hsqldb liquibase

我正在使用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设置为ON UPDATE的默认值?

3 个答案:

答案 0 :(得分:6)

您无法使用默认值执行此操作。 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子句之后。

答案 1 :(得分:5)

或者您可以尝试这样做,因为您已经添加了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不会产生您上面描述的内容。我必须如上所述处理它

答案 2 :(得分:4)

我们实际上使用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上有一个关于如何重构您可以在How do you refactor similar looking code and provide params in Liquibase?看到的部分代码的问题。