默认值ON UPDATE Liquibase

clo*_*her 10 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>
Run Code Online (Sandbox Code Playgroud)

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

`last_modified` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
Run Code Online (Sandbox Code Playgroud)

虽然如果我使用HSQLDB,在更新的情况下没有任何反应,但我希望MySQL数据库具有相同的行为,更新时的默认值等于CURRENT_TIMESTAMP.

如何将CURRENT_TIMESTAMP设置为ON UPDATE的默认值?

sak*_*zai 7

或者你可以试试这个,因为你已经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>
Run Code Online (Sandbox Code Playgroud)

Liquibase 3.1.1不会产生您上面描述的内容.我必须如上所述处理它


fre*_*edt 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子句之后.


Dav*_*off 5

我们实际上将 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>
Run Code Online (Sandbox Code Playgroud)

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