json - 在 postgresql 更新触发器上测试数据类型

标签 json postgresql triggers jsonb

我使用触发器来检测在对表执行更新时是否至少有一个值已更改。

函数:

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/

相关文章:

json - 如何制作动态JSON

python - 无法从 Trac 获取数据库连接?

java - 如何在Spring Boot中从另一个集合获取数据

json - Elasticsearch js 批量索引类型错误

Jquery DataTable 将参数传递给 ajax 调用 asp.net。无效的 JSON 原语

django - 用 Django 的 Postgres 全文搜索匹配一个或多个关键字

python "[WARNING] Retrying after connection broken by SSLError"

sql-server - 触发器的 SQL if update() 语句

MySql Stored Procedure如何处理?

mysql - 触发,不插入