liquibase sql 迁移问题

liquibase sql migration issue

我正在为一些操作编写 1 个 PostgreSQL 函数。 为该函数编写 SQL 迁移,但由于 liquibase 无法识别某些部分而面临格式错误。

函数 Liquibase 迁移:

CREATE OR REPLACE FUNCTION schema.fncn(trId integer, sts integer, stIds character varying)
 RETURNS double precision
 LANGUAGE plpgsql
AS '
DECLARE
      abc integer;
      query CHAR(1500);
      xyz   integer;
BEGIN
      query := ''select sum(t.a) 
      FROM schema.tbl t 
      where t.id in(1,2) 
      and t.status ='' || sts || 
      '' and t.status <> 2 
      and t.tr_id ='' || trId || 
      '' and t.sw in('''', ''N'')'';

      IF stIds is not null then
        query := query || '' AND t.st_id IN ('' || stIds || '')'';
      ELSE
      END IF;

      EXECUTE query INTO abc;

      SELECT abc INTO xyz;
    RETURN xyz;
END;
'
;

抛出以下错误:

原因:org.postgresql.util.PSQLException:错误:“N”处或附近的语法错误

原因:liquibase.exception.DatabaseException:错误:“N”处或附近的语法错误

有什么我遗漏的建议吗?

眼前的问题是 ' 单引号的嵌套。为了简化操作,请使用 dollar quoting 作为函数体。您可以通过选择不同的分隔符来嵌套美元引号字符串。

为避免参数连接出现任何问题,请在查询中使用 parameter place holders 并使用 USING 子句传递值。然而,这将需要两个不同的 execute 调用。

我假设 stIds 是逗号分隔的值字符串。要将其用作(单个)占位符,请使用 string_to_array() 将其转换为数组 - 甚至更好:将输入参数的类型更改为 text[] 并直接传递数组。

查询变量最好定义为textdon't use char。也不需要将查询结果复制到不同的变量中(顺便说一句,使用 xyz := abc; 而不是 select into 会更有效)

CREATE OR REPLACE FUNCTION schema.fncn(trId integer, sts integer, stIds character varying)
 RETURNS double precision
 LANGUAGE plpgsql
AS
$body$
DECLARE
      abc integer;
      query text;
BEGIN
  query := $q$ select sum(t.a) 
            FROM schema.tbl t 
            where t.id in (1,2) 
            and t.status =  
            and t.status <> 2 
            and t.tr_id = 
            and t.sw in ('''', 'N') $q$;

  IF stIds is not null then
    query := query || $sql$ AND t.st_id = ANY (string_to_array(, ',') $sql$;
    EXECUTE query INTO abc
      using trid, sts, stids;
  ELSE
    EXECUTE query INTO abc
      using trid, sts;
  END IF;
      
  RETURN abc;
END;
$body$
;

请注意,在 Liquibase 更改中,您必须使用 splitStatements=false 才能 运行 这没有错误。