我使用触发器来检测在对表执行更新时是否至少有一个值已更改。
函数:
CREATE OR REPLACE FUNCTION update_version_column()
RETURNS trigger AS
$BODY$
BEGIN
IF row(NEW.*) IS DISTINCT FROM row(OLD.*) THEN
NEW.version = now();
RETURN NEW;
ELSE
RETURN OLD;
END IF;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
ALTER FUNCTION update_version_column()
OWNER TO gamesplateform;
问题是,当列类型为“json”时,“不同”失败(标准操作,在文档中解释)。
我搜索了一种方法来执行相同的操作,但如果列是“json”类型,我想强制转换接受比较运算符的“jsonb”。
有办法吗?
谢谢!
最佳答案
找到一种方法来做到这一点:
CREATE OR REPLACE FUNCTION update_version_column()
RETURNS trigger AS
$BODY$
DECLARE
updated boolean := false;
column_data record;
BEGIN
FOR column_data IN
SELECT
column_name::varchar,
data_type::varchar
FROM information_schema.columns AS c
WHERE table_name = TG_TABLE_NAME
LOOP
IF column_data.data_type = 'json' THEN
EXECUTE format('SELECT CASE WHEN ($1).' || column_data.column_name || '::text <> ($2).' || column_data.column_name || '::text THEN true ELSE false END')
USING NEW, OLD
INTO updated;
ELSE
EXECUTE format('SELECT CASE WHEN ($1).' || column_data.column_name || ' <> ($2).' || column_data.column_name || ' THEN true ELSE false END')
USING NEW, OLD
INTO updated;
END IF;
IF updated = true THEN
NEW.version := now();
RETURN NEW;
END IF;
END LOOP;
RETURN OLD;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
ALTER FUNCTION update_version_column()
OWNER TO gamesplateform;
我将“json”转换为“text”,因为“jsonb”失败(类型不存在)。 似乎特定于我的配置,但这个触发器回答得很好 :)
谢谢@Julien Bossart!
关于json - 在 postgresql 更新触发器上测试数据类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27015839/