2

I'm trying to build a function that Insert/Update/Delete rows of a table based from another table changes. Unfortunately I could not continue, some problems occured:

  1. DELETE isn't work correctly: Any linestring cannot deleted when trigger is enabled;
  2. INSERT/UPDATE - More than 1 row is returned from query - I insert the 'DISTINCT' to fix - I don't know why;
  3. I would like to add point's manually (If possible).

The intention is create, update or delete a point for each line inserted, updated or deleted when this line have a specific atribute called 'con';

These points are generated on the center of each line;

Point table - prec_peca_receive ;

Line table - string

Here is the code:


CREATE OR REPLACE FUNCTION public.insert_peca_by_line()
 RETURNS trigger 
 LANGUAGE plpgsql
 AS $func$
BEGIN
 CASE TG_OP
 WHEN 'INSERT' THEN
 INSERT INTO public.prec_point_receive (geom) 
 select distinct st_lineinterpolatepoint(new.geom, 0.5)::geometry (point,31984)
 from public.string s
 where s.geom is not null and s.str_type = 'con';
 WHEN 'DELETE' THEN
 delete from public.prec_point_receive p
 where st_lineinterpolatepoint(old.geom, 0.5) = p.geom;
 WHEN 'UPDATE' THEN
 UPDATE public.prec_point_receive p
 set (geom) = 
 (
 select distinct st_lineinterpolatepoint(new.geom, 0.5)::geometry (point,31984)
 from string s
 where p.geom is distinct from (st_lineinterpolatepoint(new.geom, 0.5))
 and st_lineinterpolatepoint(old.geom, 0.5) in 
 (select p.geom 
 from prec_point_receive)
 );
 ELSE
 --nothing
 END CASE;
 RETURN NEW;
END;
$func$;
CREATE TRIGGER tg_peca_by_line
 BEFORE INSERT OR DELETE OR UPDATE 
 ON public.string
 FOR EACH ROW
 EXECUTE PROCEDURE public.insert_peca_by_line();

Could someone clarify?

Vince
20.5k16 gold badges49 silver badges65 bronze badges
asked May 16, 2020 at 15:25

1 Answer 1

4

For the insert, you don't need to re-select from the source table.

As it is, you are computing the centroid of the new row geometry (so 1 row) for EVERY row that has a geometry and the desired attribute. Instead, just work on the NEW record

IF NEW.str_type = 'con' THEN
 INSERT INTO public.prec_point_receive (geom) 
 select st_lineinterpolatepoint(new.geom, 0.5)::geometry (point,31984);
END IF;

For the delete and the update, you can do the same. BUT it is a bad idea to work solely on the geometry... what if two intersecting lines share the same centroid?.. both would be deleted. Instead, the proper way is to assign the same ID to your line and point, then finding the row to be updated or deleted would be done solely on the ID.

ex:

delete from public.prec_point_receive p
 where p.ID = OLD.ID
answered May 16, 2020 at 15:47

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.