2

If an entry in a table satisfies certain conditions, a NOTIFY is sent out. I want the payload to include the ID number and several other columns of information. Is there a postgres method to convert variables (OLD.ColumnID, etc) to strings?

using postgres 9.3

5 Answers 5

4

@klin is correct that NOTIFY doesn't support anything other than string literals. However there is a function pg_notify() which takes normal arguments to deal with exactly this situation. It's been around since at least 9.0 and that link is to the official documentation - always worth reading it carefully, there is a wealth of information there.

Sign up to request clarification or add additional context in comments.

Comments

2

My guess is that the notify has to be done within a trigger function. Use a dynamic query, e.g.

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

Comments

2

Sorry for the long answer, i just cant walk away without reacting to the other answers too.

The format version fails in many ways. Before EXECUTE, you shoud prepare the plan. The "pseudo command" does not fits the syntax of execute which is

EXECUTE somepreparedplanname (parameter1, ...)

The %s in format is again too bad, this way you can summon sql injection attacks. When constructing a query with format, you need to use %L for literals %I for column/table/function/etc ids, and use %s almost never.

The other solution with the pg_notify function is correct. Try

LISTEN channel;
SELECT pg_notify('channel','Id: '|| pg_backend_pid  ());

in psql command line.

So back to the original question: sdemurjian, Its not clarified in the question, if you wants to use this notification thing in some trigger function. So here is an example (maybe not) for you (because im a little late. sorry for that too):

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;

Please note that in early postgres versions (any before 9), the notify command does not accepts any payload and there is no pg_notify function.

In 8.1 the trigger function stil works if you define it like

CREATE FUNCTION column_trigger_func() RETURNS TRIGGER AS
$$ BEGIN NOTIFY columnchannel; RETURN NEW; END; $$ LANGUAGE plpgsql;

Comments

0

The solution was to upgrade Postgres to a version that supported JSON.

Comments

0

Even postgresql 9.3 supports json. You could have just used row_to_json(payload)::text

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.