You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在Liquibase中声明并运行匿名PL/pgSQL块?执行时出现SQL语法异常求助

解决PostgreSQL+Liquibase执行匿名PL/pgSQL块的语法异常问题

我来帮你搞定这个问题!你遇到的SQL语法错误,核心是匿名PL/pgSQL块的写法不符合PostgreSQL规范,再加上Liquibase的配置没适配这种复杂语句,导致解析失败。下面一步步给你修正:

1. 修正SQL文件的PL/pgSQL语法

PostgreSQL的匿名PL/pgSQL块必须用DO $$ ... $$包裹,而且变量声明要统一放在DECLARE段内,同时赋值要用规范的:=语法。把你的027-rename-psps.sql改成下面这样:

DO $$
DECLARE
    -- 声明游标和变量,全部放在DECLARE段内
    cur_rename CURSOR (modulekeyold varchar) FOR SELECT * FROM payment_module_config WHERE module_key = modulekeyold;
    counter INTEGER := 0;
    commitnum INTEGER := 100;
    -- 显式声明记录变量的类型,避免隐式类型问题
    recordvar payment_module_config%ROWTYPE;
BEGIN
    FOR recordvar IN cur_rename('WirecardPaymentService_1.0') LOOP
        RAISE NOTICE 'Value: %', recordvar;
        UPDATE payment_module_config SET module_key='GetNet V1' WHERE id = recordvar.id;
        counter := counter + 1;
        
        IF (counter % commitnum = 0) THEN
            RAISE NOTICE '>>> counter: %', counter;
            COMMIT;
        END IF;
    END LOOP;
    COMMIT;
END $$;

为什么原来的写法错了?

  • 没有用DO $$ ... $$包裹:PostgreSQL不允许直接执行裸的PL/pgSQL块,必须通过DO语句触发执行
  • 变量位置错误:countercommitnum必须放在DECLARE关键字下方,不能单独写在外面
  • 赋值语法不规范:PostgreSQL中PL/pgSQL的变量赋值推荐用:=,虽然部分版本兼容=,但规范写法能避免潜在问题
  • 记录变量未显式声明:显式指定payment_module_config%ROWTYPE让代码更清晰,也能避免隐式转换错误

2. 调整Liquibase的变更日志配置

你的Liquibase配置里,splitStatements="true"会把SQL文件里的分号当作语句分隔符,导致把完整的PL/pgSQL块拆成多个无效语句,必须关闭这个配置。修改changeSet里的sqlFile标签:

<changeSet author="wamk" id="20210909102601">
  <preConditions onFail="MARK_RAN">
    <dbms type="postgresql" />
  </preConditions>
  <sqlFile path="027-rename-psps.sql" relativeToChangelogFile="true" 
           endDelimiter=";" dbms="PostgreSQL" encoding="utf8" 
           splitStatements="false"/> <!-- 关键:关闭语句拆分 -->
</changeSet>

配置调整的原因

整个DO $$ ... $$块是一个完整的PL/pgSQL语句,内部的分号是块内的语句分隔符,不是整个SQL语句的结束符。如果splitStatements="true",Liquibase会错误地把块内的每个分号都当作独立语句的结束,导致解析失败。

做完这两步调整后,重新执行Liquibase变更,应该就能正常运行了!

内容的提问来源于stack exchange,提问作者shadow0wolf

火山引擎 最新活动