7

I want to write a pgsql function to create trigger dynamically. For example, a trigger to count insertions in each table. I've tried EXECUTE like this:

CREATE FUNCTION trigen(tbl text) RETURNS void AS $$
BEGIN
    EXECUTE format(
    'CREATE FUNCTION %s_insertCnt() RETURNS TRIGGER AS $$
    BEGIN
        UPDATE insertions SET n = n + 1 WHERE tablename = %s;
    END
    $$ LANGUAGE plpgsql', tbl, quote_nullable(tbl));

    EXECUTE format('CREATE TRIGGER %s_inCnt BEFORE INSERT ON %s
    FOR EACH ROW EXECUTE PROCEDURE %s_insertCnt();', tbl, tbl, tbl);
END
$$ LANGUAGE plpgsql

But this approach doesn't work. A lot of syntax error occurred when I import this code. It seems that EXECUTE cannot execute a function creation.

What else can I do to create trigger functions dynamically?

2
  • 1
    I think the problem is the nested $$. To nest dollar-quoted literals, you need to pick different tags. See the docs for details. Commented Jul 20, 2015 at 3:34
  • And why would you want to do this? Why dynamically? Commented Jul 20, 2015 at 3:44

1 Answer 1

5

The two $$ sections were getting confused. By using the $name$ syntax instead you can separate these.

Also the trigger was missing a RETURN.

CREATE OR REPLACE FUNCTION trigen(tbl text) RETURNS void AS $T1$
BEGIN
    EXECUTE format(
    'CREATE FUNCTION %s_insertCnt() RETURNS TRIGGER AS $T2$
    BEGIN
        UPDATE insertions SET n = n + 1 WHERE tablename = %s;
        RETURN NEW;
    END
    $T2$ LANGUAGE plpgsql', tbl, quote_nullable(tbl));

    EXECUTE format('CREATE TRIGGER %s_inCnt BEFORE INSERT ON %s
    FOR EACH ROW EXECUTE PROCEDURE %s_insertCnt();', tbl, tbl, tbl);
    END
$T1$ LANGUAGE plpgsql;
Sign up to request clarification or add additional context in comments.

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.