【问题标题】:How can I send column values as the payload in a postgresql NOTIFY message?如何在 postgresql NOTIFY 消息中将列值作为有效负载发送?
【发布时间】:2016-01-10 06:44:26
【问题描述】:

如果表中的条目满足某些条件,则会发出 NOTIFY。我希望有效负载包含 ID 号和其他几列信息。是否有 postgres 方法将变量(OLD.ColumnID 等)转换为字符串?

使用 postgres 9.3

【问题讨论】:

    标签: postgresql notify listen


    【解决方案1】:

    @klin 是正确的,NOTIFY 不支持字符串文字以外的任何内容。然而,有一个函数pg_notify() 采用普通参数来处理这种情况。它至少从 9.0 开始就存在,并且该链接指向官方文档 - 始终值得仔细阅读,那里有大量信息。

    【讨论】:

      【解决方案2】:

      我的猜测是通知必须在触发函数中完成。使用动态查询,例如

      execute format('notify channel, ''id: %s''', old.id);
      

      【讨论】:

        【解决方案3】:

        解决方案是将 Postgres 升级到支持 JSON 的版本。

        【讨论】:

          【解决方案4】:

          甚至 postgresql 9.3 也支持 json。你可以使用row_to_json(payload)::text

          【讨论】:

            【解决方案5】:

            对不起,回答太长了,我也不能不回应其他答案就走开。

            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;
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2013-12-07
              • 1970-01-01
              • 1970-01-01
              • 2023-04-05
              • 2018-01-01
              相关资源
              最近更新 更多