Em 15 de novembro de 2010 14:38, Eloi Ribeiro <[email protected]> escreveu:
> Olá à lista,
> Queria fazer um disparador sobre uma tabela com dois campos do
> tipo 'Geometry' (geom_23030 e geom_4258) cada um com um sistema de
> coordenadas diferente.
> A ideia era que o disparador actualiza-se o segundo campo sempre que
> houvesse um INSERT ou UPDATE no primeiro campo e assim tivessem sempre a
> mesma geometria mas cada um dos campos com o seu respectivo sistemas de
> coordenadas.
> Devido à minha falta de experiência em plpgsql eu não sei como fazer para
> que o disparador reconheça qual a geometria mais recente e proceder com
> a actualização da mais antiga. Como tenho feito, actualiza por ordem de como
> está indicado no disparador sem ter em conta a antiguidade. Deveria
> adicionar dois novos campos com Time Stamp de cada uma das geometrias para
> conseguir o meu objectivo?
> Estou a usar algumas das funções disponibilizadas pela extensão PostGIS.
> Isto foi o que consegui fazer:
> --SELECT DropGeometryColumn('sch_temp','teste','geom_23030');
> --SELECT DropGeometryColumn('sch_temp','teste','geom_4258');
> --DROP TABLE sch_temp.teste;
> CREATE TABLE sch_temp.teste (gid serial primary key, longitude double
> precision);
> SELECT AddGeometrycolumn
> ('sch_temp','teste','geom_23030',23030,'LINESTRING',2);
> SELECT AddGeometrycolumn
> ('sch_temp','teste','geom_4258',4258,'LINESTRING',2);
> CREATE OR REPLACE FUNCTION funcao_teste() RETURNS trigger AS
> $$
> BEGIN
> -- Se o campo geom_4258 tem um novo INSERT ou UPDATE, entao actualiza
> geom_23030.
> NEW.geom_23030 = ST_Transform((NEW.geom_4258), 23030);
>
> -- Se o campo geom_23030 tem um novo INSERT ou UPDATE, entao actualiza
> geom_4258.
> NEW.geom_4258 = ST_Transform((NEW.geom_23030), 4258);
> -- Calcula/actualiza a longitude da geometria.
> NEW.longitude  = ST_Length(NEW.geom_23030);
> RETURN NEW;
> END;
> $$ LANGUAGE plpgsql;
> DROP TRIGGER IF EXISTS funcao_teste ON sch_temp.teste;
> CREATE TRIGGER funcao_teste BEFORE INSERT OR UPDATE ON sch_temp.teste FOR
> EACH ROW EXECUTE PROCEDURE funcao_teste();
> INSERT INTO sch_temp.teste(geom_23030)
> VALUES(ST_GeomFromText('SRID=23030;LINESTRING(232400 4548000,700882
> 4548000)'));
> INSERT INTO sch_temp.teste(geom_4258) VALUES
> (ST_GeomFromText('SRID=4258;LINESTRING(-6 38,-1 38)'));
> UPDATE sch_temp.teste SET geom_4258 =
> ST_GeomFromText('SRID=4258;LINESTRING(-5 37,-1 37)') WHERE gid = 2;
> SELECT gid, longitude, ST_AsText(geom_23030), ST_AsText(geom_4258) FROM
> sch_temp.teste;
> Obrigado. Cumprimentos,
>


Pelo que entendi você deve:
- verificar qual é a operação (TG_OP);
- se for INSERT, verificar em NEW qual foi a informada e calcular a
outra, colocando o resultado em NEW;
- se for UPDATE, verificar qual foi alterada e calcular a que não foi
alterada, colocando o resultado em NEW;

CREATE OR REPLACE FUNCTION funcao_teste() RETURNS trigger AS
$$
BEGIN
IF (TG_OP = 'INSERT') THEN
        IF (NEW.geom_4258 IS NOT NULL) THEN
                -- Se o campo geom_4258 tem um novo INSERT, entao actualiza 
geom_23030.
                NEW.geom_23030 = ST_Transform((NEW.geom_4258), 23030);
        ELSE
                -- Se o campo geom_23030 tem um novo INSERT, entao actualiza 
geom_4258.
                NEW.geom_4258 = ST_Transform((NEW.geom_23030), 4258);
        END IF;
ELSE
        IF (TG_OP = 'UPDATE') THEN
                IF (NEW.geom_4258 IS NOT NULL) THEN
                        NEW.geom_23030 = ST_Transform((NEW.geom_4258), 23030);
                ELSE
                        IF (OLD.geom_23030 IS NOT NULL) THEN
                                NEW.geom_4258 = ST_Transform((NEW.geom_23030), 
4258);
                        END IF;
                END IF;
END IF;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;

ou algo nesta linha.

Osvaldo
_______________________________________________
pgbr-geral mailing list
[email protected]
https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral

Responder a