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