2010/11/16 Osvaldo Kussama <[email protected]>

> 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
>


Obrigado Osvaldo, era isso mesmo que queria fazer.
Apenas nao funciona o ultimo UPDATE.
Simplificando o exemplo anterior:

--DROP TABLE sch_temp.teste;
CREATE TABLE sch_temp.teste (id serial primary key, x int, x100 int);

CREATE OR REPLACE FUNCTION funcao_teste() RETURNS trigger AS
$$
BEGIN
IF (TG_OP = 'INSERT') THEN
       IF (NEW.x IS NOT NULL) THEN
               NEW.x100 = NEW.x*100;
       ELSE
               NEW.x = NEW.x100/100;
       END IF;
ELSE
       IF (TG_OP = 'UPDATE') THEN
               IF (NEW.x IS NOT NULL) THEN
                       NEW.x100 = NEW.x*100;
               ELSE
        IF (OLD.x100 IS NOT NULL) THEN
       NEW.x = NEW.x/100;
END IF;
               END IF;
        END IF;
END IF;
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(x) VALUES(1);
INSERT INTO sch_temp.teste(x100) VALUES (200);
SELECT * FROM sch_temp.teste;
1;1;100
2;2;200

Os INSERTS funcionam na perfeição.

UPDATE sch_temp.teste SET x = 3 WHERE x = 2;
SELECT * FROM sch_temp.teste;
1;1;100
2;3;300

O primeiro UPDATE também.

UPDATE sch_temp.teste SET x100 = 200 WHERE x = 3;
SELECT * FROM sch_temp.teste;
1;1;100
2;3;300

Excepto este ultimo que não dispara. Porque?
Aqui o resultado deveria ser:
1;1;100
2;2;200

Obrigado por toda a ajuda.

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

Responder a