【问题标题】:How can I create triggers for a postgreSQL db using liquibase?如何使用 liquibase 为 postgreSQL 数据库创建触发器?
【发布时间】:2013-09-16 01:36:35
【问题描述】:

我正在使用 dropwizard-migrations 模块进行 liquibase 数据库重构。请参阅此处的指南:http://dropwizard.codahale.com/manual/migrations/

当我跑步时 java -jar my_project.jar db migrate my_project.yml

我收到以下错误:

错误 [2013-09-11 20:53:43,089] liquibase:更改集 migrations.xml::11::me 失败。错误:执行 SQL CREATE OR REPLACE TRIGGER add_current_date_to_my_table 在更新 my_table FOR EACH ROW EXECUTE PROCEDURE change_update_time() 之前出错:错误:在“TRIGGER”处或附近出现语法错误 职位:19

以下是我的 migrations.xml 文件中的一些相关变更集:

<changeSet id="1" author="me">
    <createProcedure>
        CREATE OR REPLACE FUNCTION change_update_time() RETURNS trigger
        LANGUAGE plpgsql
        AS $$
        BEGIN
        NEW.updated_at := CURRENT_TIMESTAMP;
        RETURN NEW;
        END;
        $$;
    </createProcedure>
    <rollback>
        DROP FUNCTION change_update_time();
    </rollback>
</changeSet>        

<changeSet id="2" author="me">
    <preConditions>
        <not>
            <tableExists tableName="my_table"/>
        </not>
    </preConditions>

    <createTable tableName="my_table">
        <column name="_id" type="integer" defaultValue="0">
            <constraints nullable="false"/>
        </column>
        <column name="updated_at" type="timestamp without time zone" defaultValue="now()">
            <constraints nullable="false"/>
        </column>
    </createTable>
</changeSet>

<changeSet id="3" author="me">
    <sql splitStatements="false">
        CREATE OR REPLACE TRIGGER add_current_date_to_my_table BEFORE UPDATE ON my_table FOR EACH ROW EXECUTE PROCEDURE change_update_time();
    </sql>
    <rollback>
        DROP TRIGGER add_current_date_to_my_table ON my_table;
    </rollback>
</changeSet>

有什么方法可以创建触发器 add_current_date_to_my_table?这与创建函数的“RETURNS 触发器”是否多余?

【问题讨论】:

  • 我根本不了解 Postgres,但存储过程可以自己工作吗?您收到的错误消息来自 postgres。 “创建或替换触发器”是否有效?快速谷歌搜索显示触发器可能会像DROP TRIGGER IF EXISTS... 一样被丢弃。无论如何。尝试先手动创建触发器并确保它有效。 Liquibase 只会执行相同的 SQL。

标签: postgresql liquibase dropwizard


【解决方案1】:

解决办法是:

<changeSet id="3" author="me">
    <sql>
        DROP TRIGGER IF EXISTS add_current_date_to_my_table ON my_table;
        CREATE TRIGGER add_current_date_to_my_table BEFORE UPDATE ON my_table FOR EACH ROW EXECUTE PROCEDURE change_update_time();
    </sql>
    <rollback>
        DROP TRIGGER add_current_date_to_my_table ON my_table;
    </rollback>
</changeSet>

H/T 詹斯。

【讨论】:

    【解决方案2】:

    Ann Kilzer 提供了正确的答案,因为 Postgres 中没有 CREATE OR REPLACE 语句,这与 PL/SQL 不同。

    所以我们需要把这条语句拆分成2个原子操作:

    1. DROP TRIGGER
    2. CREATE TRIGGER

    【讨论】:

    • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
    猜你喜欢
    • 2015-09-14
    • 1970-01-01
    • 1970-01-01
    • 2012-05-14
    • 2021-08-04
    • 1970-01-01
    • 2017-07-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多