PostgreSQL – How to Create a Trigger Function to Update Column

functionsplpgsqlpostgresql-9.5trigger

I'm a newbie to PL/pgSQL … I use Postgres 9.5.0, and need to update a column every time a new record is inserted. The column shall be filled in from the values entered in area_pol and area_ofi.

I'm trying to create this function to suit my case:

CREATE OR REPLACE FUNCTION sch_cap.fc_atualiza_dif_area()
  RETURNS trigger AS
$$
BEGIN
    UPDATE
        sch_cap.tbl_cap
    SET
        dif_area = abs(100 - (tbl_cap.area_pol / (tbl_cap.area_ofi * 100)));
END;
$$
LANGUAGE plpgsql;

CREATE TRIGGER tg_atualiza_dif_area
  BEFORE INSERT OR UPDATE ON sch_cap.tbl_cap
  FOR EACH ROW EXECUTE PROCEDURE sch_cap.fc_atualiza_dif_area();

But when I try to insert a record, the following error appears:

ERROR: stack depth limit exceeded
HINT: Increase the configuration parameter "max_stack_depth" (currently 2048kB), after ensuring the platform's stack depth limit is adequate.

How to get it right?

Best Answer

need to update a column every time a new record is inserted

Your description contradicts the trigger definition with BEFORE INSERT OR UPDATE. Either just BEFORE INSERT or the description is wrong.

Next, your whole trigger function is a misunderstanding. Would just be:

CREATE OR REPLACE FUNCTION sch_cap.fc_atualiza_dif_area()
  RETURNS trigger AS
$func$
BEGIN
   NEW.dif_area := abs(100 - (NEW.area_pol / (NEW.area_ofi * 100)));
END
$func$  LANGUAGE plpgsql;

Just assign the desired value before the row is inserted. (No SET here.)

But really, I would use the VIEW Evan suggested.
As for your comment, if QGIS somehow messes with the automatic feature of updatable views (like you state in the related question on gis.SE), just keep writing to the table directly. The VIEW is for representation only in this case, to display the additional, functionally dependent column.