Значение по умолчанию ПРИ ОБНОВЛЕНИИ 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 в качестве значения по умолчанию при обновлении?


person cloudy_weather    schedule 07.10.2013    source источник


Ответы (3)


Вы не можете сделать это со значением по умолчанию. Поведение 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.

person fredt    schedule 10.10.2013

Или вы можете попробовать это, так как вы уже добавили тег 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 не производит того, что вы описали выше. Я должен иметь дело с этим, как указано выше

person sakhunzai    schedule 19.05.2014

мы фактически используем Liquibase для точно такого же варианта использования. Вы захотите создать триггер обновления, как описал Фредт. В противном случае вы не можете быть уверены, что обновление произойдет в других базах данных, кроме MySQL. Ваш тег набора изменений будет регистрировать что-то вроде этого:

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

Кроме того, у меня есть вопрос о переполнении стека о том, как реорганизовать часть этого кода, который вы можете увидеть по адресу Как вы рефакторите похожий код и предоставляете параметры в Liquibase?.

person David Groff    schedule 30.10.2013