在 Liquibase 中创建函数时 "OLD <> NEW" 处出错
Error at "OLD <> NEW" when creating function in Liquibase
我正在尝试使用 Liqubase 创建触发器函数。以下是我的更改集:
<changeSet id="1" author="valen" dbms ="postgresql" >
<createProcedure>
CREATE OR REPLACE FUNCTION public.onupdate_update_mod_ver()
RETURNS trigger
LANGUAGE plpgsql
AS $function$
BEGIN
IF NEW <> OLD THEN
UPDATE mod_ver SET rec_change_date = current_timestamp where id = new.id;
END IF;
RETURN NEW;
END;
$function$;
</createProcedure>
<rollback>
DROP FUNCTION onupdate_update_mod_ver();
</rollback>
</changeSet>
它在 IF NEW <> OLD THEN
行抛出语法错误。
它说 tag name expected
。基本上它读取 <>
作为标签而不是“不等于”。
我尝试使用 !=
但没有成功。
注意:直接在数据库中执行该函数是正确的,但是如果有更改日志就不行了。我也尝试使用 <sql>
标签将其简单地写成语句但仍然是同样的错误。
知道如何绕过这个问题吗?
由于 Liquibase 使用 XML 格式,将整个 CREATE FUNCTION
语句包装在 CDATA
section 中以转义所有包含的字符,否则识别为标记:
<changeSet id="1" author="valen" dbms ="postgresql">
<createProcedure>
<![CDATA[
CREATE OR REPLACE FUNCTION public.onupdate_update_mod_ver()
RETURNS trigger
LANGUAGE plpgsql AS
$func$
BEGIN
IF NEW IS DISTINCT FROM OLD THEN
UPDATE public.mod_ver
SET rec_change_date = CURRENT_TIMESTAMP
WHERE id = NEW.id;
END IF;
RETURN NEW;
END
$func$
]]>
</createProcedure>
<rollback>
DROP FUNCTION public.onupdate_update_mod_ver()
</rollback>
</changeSet>
除了<
之外,$
(用于美元引用函数体)也有特殊含义。
参见:
- What does <![CDATA[]]> in XML mean?
同时我添加了一些其他建议:
如果在创建时对函数进行模式限定是有意义的,那么在删除时进行同样的操作也是有意义的。 (并以相同的方式对更新后的 table 进行架构限定。)
如果任何行包含 NULL
字段,NEW <> OLD
将失败。如果所有涉及的列都已定义 NOT NULL
没关系。否则使用 NEW IS DISTINCT FROM OLD
代替。
缩进,trim噪音。
我正在尝试使用 Liqubase 创建触发器函数。以下是我的更改集:
<changeSet id="1" author="valen" dbms ="postgresql" >
<createProcedure>
CREATE OR REPLACE FUNCTION public.onupdate_update_mod_ver()
RETURNS trigger
LANGUAGE plpgsql
AS $function$
BEGIN
IF NEW <> OLD THEN
UPDATE mod_ver SET rec_change_date = current_timestamp where id = new.id;
END IF;
RETURN NEW;
END;
$function$;
</createProcedure>
<rollback>
DROP FUNCTION onupdate_update_mod_ver();
</rollback>
</changeSet>
它在 IF NEW <> OLD THEN
行抛出语法错误。
它说 tag name expected
。基本上它读取 <>
作为标签而不是“不等于”。
我尝试使用 !=
但没有成功。
注意:直接在数据库中执行该函数是正确的,但是如果有更改日志就不行了。我也尝试使用 <sql>
标签将其简单地写成语句但仍然是同样的错误。
知道如何绕过这个问题吗?
由于 Liquibase 使用 XML 格式,将整个 CREATE FUNCTION
语句包装在 CDATA
section 中以转义所有包含的字符,否则识别为标记:
<changeSet id="1" author="valen" dbms ="postgresql">
<createProcedure>
<![CDATA[
CREATE OR REPLACE FUNCTION public.onupdate_update_mod_ver()
RETURNS trigger
LANGUAGE plpgsql AS
$func$
BEGIN
IF NEW IS DISTINCT FROM OLD THEN
UPDATE public.mod_ver
SET rec_change_date = CURRENT_TIMESTAMP
WHERE id = NEW.id;
END IF;
RETURN NEW;
END
$func$
]]>
</createProcedure>
<rollback>
DROP FUNCTION public.onupdate_update_mod_ver()
</rollback>
</changeSet>
除了<
之外,$
(用于美元引用函数体)也有特殊含义。
参见:
- What does <![CDATA[]]> in XML mean?
同时我添加了一些其他建议:
如果在创建时对函数进行模式限定是有意义的,那么在删除时进行同样的操作也是有意义的。 (并以相同的方式对更新后的 table 进行架构限定。)
如果任何行包含 NEW <> OLD
将失败。如果所有涉及的列都已定义NOT NULL
没关系。否则使用NEW IS DISTINCT FROM OLD
代替。缩进,trim噪音。
NULL
字段,