【发布时间】:2016-01-10 06:44:26
【问题描述】:
如果表中的条目满足某些条件,则会发出 NOTIFY。我希望有效负载包含 ID 号和其他几列信息。是否有 postgres 方法将变量(OLD.ColumnID 等)转换为字符串?
使用 postgres 9.3
【问题讨论】:
标签: postgresql notify listen
如果表中的条目满足某些条件,则会发出 NOTIFY。我希望有效负载包含 ID 号和其他几列信息。是否有 postgres 方法将变量(OLD.ColumnID 等)转换为字符串?
使用 postgres 9.3
【问题讨论】:
标签: postgresql notify listen
@klin 是正确的,NOTIFY 不支持字符串文字以外的任何内容。然而,有一个函数pg_notify() 采用普通参数来处理这种情况。它至少从 9.0 开始就存在,并且该链接指向官方文档 - 始终值得仔细阅读,那里有大量信息。
【讨论】:
我的猜测是通知必须在触发函数中完成。使用动态查询,例如
execute format('notify channel, ''id: %s''', old.id);
【讨论】:
解决方案是将 Postgres 升级到支持 JSON 的版本。
【讨论】:
甚至 postgresql 9.3 也支持 json。你可以使用row_to_json(payload)::text
【讨论】:
对不起,回答太长了,我也不能不回应其他答案就走开。
format 版本在很多方面都失败了。在执行之前,您应该准备好计划。 “伪命令”不符合执行的语法,即
EXECUTE somepreparedplanname (parameter1, ...)
格式的%s又太糟糕了,这样你就可以召唤sql注入攻击了。使用format 构造查询时,您需要将 %L 用于文字 %I 用于列/表/函数/等 id,并且几乎从不使用 %s。
pg_notify 函数的另一种解决方案是正确的。试试
LISTEN channel;
SELECT pg_notify('channel','Id: '|| pg_backend_pid ());
在 psql 命令行中。
回到原来的问题:sdemurjian, 如果您想在某些触发功能中使用此通知,则问题中没有说明。所以这是一个给你的例子(也许不是)(因为我有点晚了。对此也很抱歉):
CREATE TABLE columns("columnID" oid, "columnData" text);
CREATE FUNCTION column_trigger_func() RETURNS TRIGGER AS
$$ BEGIN PERFORM pg_notify('columnchannel', 'Id: '||OLD."columnID");
RETURN NEW; END; $$ LANGUAGE plpgsql;
CREATE TRIGGER column_notify BEFORE UPDATE ON columns FOR EACH ROW
EXECUTE PROCEDURE column_trigger_func();
LISTEN columnchannel;
INSERT INTO columns VALUES(1,'testdata');
BEGIN; UPDATE columns SET "columnData" = 'success'; END;
BEGIN; UPDATE columns SET "columnData" = 'fail'; ROLLBACK;
请注意,在早期的 postgres 版本(9 之前的任何版本)中,notify 命令不接受任何有效负载并且没有 pg_notify 函数。
在 8.1 中,如果您像这样定义触发器函数,它仍然可以工作
CREATE FUNCTION column_trigger_func() RETURNS TRIGGER AS
$$ BEGIN NOTIFY columnchannel; RETURN NEW; END; $$ LANGUAGE plpgsql;
【讨论】: