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[]
并直接传递数组。
查询变量最好定义为text
、don'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
才能 运行 这没有错误。
我正在为一些操作编写 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[]
并直接传递数组。
查询变量最好定义为text
、don'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
才能 运行 这没有错误。