Trigger propagation in PostgreSQL inheritance - postgresql

I am working with postgreSOL. I have a parent table and child table, which inherits the parent table.I create a trigger for the parent table. Is this trigger is propagated to child table? Any possible techniques to inherit the trigger also is available?

No, it isn't. You should write another trigger for the child table. Based on what your trigger should do, in same situations you can use the trigger on the parent table. For example, that trigger could decide in which table the data should go depending on some condition if an 'insert' query is made for the parent table.

Related

Main table update call trigger on partition

I have a table let's call it movie that is partitioned by genre.
I have a trigger defined on one of the partitions as follows:
create trigger refresh after insert or update or delete
on movie_comedy
for each statement execute procedure refresh();
This trigger is used to update a materialized view.
If I do an update on movie_comedy the trigger is called but if I update the movie table the trigger doesn't get called. The updated row is on movie_comedy as well.
Is it possible to make this happen?
You'd have to create a trigger on the partitioned table itself for that.

Before and After trigger on the same event? Fill a child table PostgreSQL

Situation
I have a database in PostgreSQL 9.5 used to store object locations by time.
I have a main table named "position" with the columns (only relevant):
position_id
position_timestamp
object_id
It is partitioned into 100 child tables on object_id with the condition:
CREATE TABLE position_object_id_00
( CHECK object_id%100 = 0 )
INHERITS ( position );
And so on for the others children. I partitioned with a modulus relation to distribute equally the objects.
Each child is indexed on position_id and object_id (two different indexes).
The trigger to redirect inserts on children is:
CREATE TRIGGER insert_position_trigger
BEFORE INSERT ON position
FOR EACH ROW EXECUTE PROCEDURE insert_position();
And the procedure insert_position() looks for the right child table to insert the data, inserts it and then return the NEW object:
CREATE OR REPLACE FUNCTION insert_position() RETURNS TRIGGER AS $insert_position$
DECLARE
BEGIN
--Look for child table
[...]
--Insert data in right child table
[...]
RETURN NEW;
END;
$insert_position$ LANGUAGE plpgsql;
I have a summary table object_last_known_position with the same columns that is updated with the trigger:
CREATE TRIGGER update_object_last_known_position
AFTER INSERT OR UPDATE ON position
FOR EACH ROW
EXECUTE PROCEDURE update_object_last_known_position();
The procedure update_object_last_known_position() basically checks if the position_timestamp is more recent, then delete the older entry and create a new entry with the data passed on the INSERT or UPDATE query (NEW).
Issue
So these two triggers react to the same event: insert on position, one is before, the other is after
Returning new for insert_position() allows me to use NEW in the trigger update_object_last_known_position(), and this is absolutely necessary. But doing that, it also insert the data on the master table position. So my data is now duplicated.
I tried to put the two triggers before, they both execute when I insert data if I let it like that, but if I remove the "return new" from the procedure insert_position(), update_object_last_known_position() is not executed.
I am stuck with this issue and I didn't find a way to execute both of these triggers without filling the master table position when I insert data.
So if you have any ideas, I will really appreciate :)
Thank you for your help!
EDIT
Solution
Thanks to the answer
I "merged" my two triggers: insert_position() now calls update_object_last_known_position directly. For that, I modified update_object_last_known_position to a stored procedure with a parameter. The parameter is the id of the position insert_position() just created, so I am able to find it and retrieve information.
(Calling update_object_last_known_position inside the other trigger means we cannot use NEW anymore)
And obviously return type for insert_position() is now NULL, and everything works fine :)
If I understand you correctly you are trying to:
Stop the insert, and replace it with an insert into another table (determined by the trigger)
Update a summary table (delete/insert) to point to the new row.
Your problem is that 1 stops 2 from happening? That's logical because you've stopped the insert so you've stopped any processing on the insert as well.
So to solve this you have a couple of options (options 1 and 2 are similar)
Call update_object_last_known_position() from insert_position() and only have one trigger
Create a wrapper method for both insert_position() and update_object_last_known_position() and have only one trigger.
Put the trigger for update_object_last_known_position() on all of the tables that insert_position() might insert into.

Access 2010 Insert Trigger

I have a parent table (Assessment) with two children tables with 1 to 1 relationships defined. To make sure that a child row is never added that does not have a parent entry, I want to add an insert trigger to the child table (ConsequenceAssessment) in this case. The following ConsequenceAssessment BeforeChange trigger fires but I cannot find how to reference the INSERTED rowset. There is an OLD recordset that works for an update; but, how do I access the inserted row. The following is my best attempt - but, the ConsequenceAssessment table does not yet include the new row and therefore, the trigger always hits the RaiseError.
UPDATE: Just found out that I can enforce Referential Integrity on a one-to-one relationship within Access (rookie misunderstanding). I would still like to know how to access the updated recordset. With MS SQL Server, this is implemented via the INSERTED table which is available within the scope of an INSERT trigger. So, what is the equivalent in MS Access.
In a Before Change data macro, [fieldname] refers to the new value and [old].[fieldname] refers to the old value (which would be Null for an insert).
In your particular case [ConsequenceAssessment].[id] appears to be the primary key for that table, not a foreign key referring to the [Assessment] (parent) table. So, the lookup is simply searching for the wrong key value in the parent table.

use case for finding foreign key with a trigger or function

Sample Code:
https://gist.github.com/telagraphic/be35fd3506f912c7a91c
I have a trigger that is throwing a data type constraint on a column.
Makes sense as to why it is throwing the error, but I thought the trigger would update the value before it gets inserted.
I have found an alternate solution of using a function in the insert to retrieve the foreign key.
My question is it possible to use a trigger to find and insert the foreign key? Or is a function the preferred method?
Looking at your code, I think you are trying to populate the category field for the INSERT into EXPENSES table, based on the ID from the CATEGORIES table using the Category name.
If I understand this right, then you should use the function in your solution and not the trigger. Triggers only get invoked or fired, when a DML statement (INSERT, UPDATE, DELETE) is executed on a table - in this case the CATEGORIES table. Since you are inserting into the EXPENSES table, the trigger on the CATEGORIES table will not be invoked.
Also, typically you generally use triggers on parent tables in a relation to update/populate the child tables in that relation. I think in your case you are trying to do the reverse, since it seems EXPENSES is a child of CATEGORIES on the CATEGORY_ID field.
Hope this helps.

TSQL For Triggers

Sorry but I'm struggling with the online documentation.
What exactly is the difference for a FOR trigger compared to a AFTER and INSTEAD OF?
Thanks
The FOR and the AFTER trigger is the same. You specify them in the same way and they do the same thing:
CREATE TRIGGER sometrigger on sometable FOR INSERT,UPDATE,DELETE
CREATE TRIGGER sometrigger on sometable AFTER INSERT,UPDATE,DELETE
The INSTEAD OF trigger is something completely different. When you specify a trigger with the instead of then the trigger will execute instead of the insert, update and delete. This can be useful when you have views. So you can control what should be delete, updated and inserted in the views underlying tables
Here is an link to explain the triggers in more depth