CYBERTEC PostgreSQL Logo

Using multiple triggers on the same table in PostgreSQL

11.2023 / Category: / Tags: |

“Developers, developers, developers, …” - let us not remind ourselves of this painful Microsoft presentation which was given by Mr Ballmer some time ago. But what happens if we deploy triggers, triggers, triggers in PostgreSQL? And what happens if we deploy them all on the very same table? That's an interesting question, and important to consider when writing triggers. What order do the multiple triggers fire in? Let's understand trigger execution order, but first, the syntax.

The syntax of CREATE TRIGGER

The CREATE TRIGGER command has become really powerful over the years. It offers a ton of functionality which we can use to leverage the power of our applications, here's the syntax from the documentation:

As you can see, PostgreSQL will call a function when a trigger is executed. The beauty here is that PostgreSQL allows us to deploy as many triggers as we want on the very same table. The logical question then is: In which order are triggers executed? Can we expect deterministic execution order, or are things simply random?

The execution order of triggers in PostgreSQL

The good news is: triggers in PostgreSQL are not random. They follow a certain execution order.

The rule is:

PostgreSQL first executes statement-level BEFORE triggers, then row-level BEFORE triggers, then row-level AFTER triggers and finally statement-level AFTER triggers. If more than one trigger in the same category exists, they are executed in alphabetical order according to the trigger name.

(this holds true since PostgreSQL 7.3, which is around 20 years old).

In short: We can rely on a deterministic order.

The following code shows a basic example:

What happens here is that we have a ton of triggers on the same table. It's also important to see that we deploy the triggers in non-alphabetical order (we can deploy them in any order but to prove the point we used the “wrong” order).

This code snippet shows what really happens:

The most important observation is that PostgreSQL does not care about the deployment order. As stated before, the entire order is fully deterministic. The TG_NAME variable which is set in every trigger by default shows us the name of the trigger that's about to execute.

Note: the PostgreSQL execution order diverges from the order decreed by the SQL standard. That states that the triggers should execute in the order they were defined.

Finally …

 

2 responses to “Using multiple triggers on the same table in PostgreSQL”

  1. Hello Hans and thx for your article

    What do you think is the best use of triggers? In my experience, triggers are often used to perform application actions (for example if update here, do calculations and update data in an another table). I think it's best to leave the application code... in the code and not in the database.

    • I wouldn't put application code in triggers. But triggers are indispensable for everything that has to do with the integrity and consistency of the database.

      Your example is a case in point: to maintain redundant data in the database reliably, you need a trigger. Also, to preprocess data that gets inserted (converting to lower case etc.), a trigger is the way to go.

      Yes, you can do all these things from the application, but that's more complicated and error-prone than doing it with a trigger (you could forget a code path). But with a solution in the application, any manual intervention in the database will likely break consistency. With a trigger, there is a guarantee that this cannot happen.

      My soft rule: if the code is too long and too complicated, it shouldn't be a trigger. If it is about simple rules that concern consistency in the database, it is probably a trigger.

Leave a Reply

Your email address will not be published. Required fields are marked *

CYBERTEC Logo white
CYBERTEC PostgreSQL International GmbH
Römerstraße 19
2752 Wöllersdorf
Austria

+43 (0) 2622 93022-0
office@cybertec.at

Get the newest PostgreSQL Info & Tools


    This site is protected by reCAPTCHA and the Google Privacy Policy & Terms of Service apply.

    ©
    2024
    CYBERTEC PostgreSQL International GmbH
    phone-handsetmagnifiercrosscross-circle
    linkedin facebook pinterest youtube rss twitter instagram facebook-blank rss-blank linkedin-blank pinterest youtube twitter instagram