2011/3/25 Osvaldo Kussama <osvaldo.kuss...@gmail.com>

> 2011/3/25, Eloi Ribeiro <eloi.ribe...@gmail.com>:
> > On Fri, Mar 25, 2011 at 13:57, Osvaldo Kussama
> > <osvaldo.kuss...@gmail.com>wrote:
> >
> >> 2011/3/25, Eloi Ribeiro <eloi.ribe...@gmail.com>:
> >> > Ola a toda a lista,
> >> >
> >> > Tenho uma tabela de *incendios* (com geometria de polígonos) onde se
> >> > encontram os perímetros de incêndios florestais.
> >> > Outra *admin* (com geometria de polígonos) com as divisões
> >> administrativas.
> >> > E uma terceira *resumo* (alfanumérica) onde quero que o seguinte
> >> disparador
> >> > guarde a superfície afectada por incêndio e município.
> >> >
> >> > Até aqui tudo bem, o problema vem quando faça um UPDATE de um
> >> > determinado incêndio, alterando a sua geometria/superfície, o
> disparador
> >> > deve eliminar previamente os registos originados pelo INSERT e
> >> > recalcular
> >> > a superfície afectada por incêndio e município. Não sei como eliminar
> os
> >> > registos desactualizados baseando-me no codigo de incendio
> (fire_code).
> >> >
> >> > -----------------------------------------------------
> >> > -- tabela incendios
> >> > CREATE TABLE sch_temp.incendios (gid SERIAL PRIMARY KEY, fir_code
> >> BIGINT);
> >> > SELECT AddGeometrycolumn
> >> ('sch_temp','incendios','geom',23030,'POLYGON',2);
> >> >
> >> > -- tabela municipios
> >> > CREATE TABLE sch_temp.municipios (adm_code INT, adm_name VARCHAR(50));
> >> > SELECT AddGeometrycolumn
> >> ('sch_temp','municipios','geom',23030,'POLYGON',2);
> >> > INSERT INTO sch_temp.municipios(adm_code,adm_name, geom)
> >> > VALUES(101,'Muni
> >> > a', ST_GeomFromText('SRID=23030;POLYGON((725000 4430000,730000
> >> > 4430000,730000 4425000,725000 4430000))'));
> >> > INSERT INTO sch_temp.municipios(adm_code,adm_name, geom)
> >> > VALUES(102,'Muni
> >> > b', ST_GeomFromText('SRID=23030;POLYGON((725000 4430000,730000
> >> > 4425000,725000 4425000,725000 4430000))'));
> >> >
> >> > -- tabela resumo
> >> > CREATE TABLE sch_temp.resumo (id SERIAL PRIMARY KEY, fir_code BIGINT,
> >> > adm_code INT, adm_area BIGINT);
> >> >
> >> > -- disparador
> >> > CREATE OR REPLACE FUNCTION funcao_incendios() RETURNS trigger AS
> >> > $fire_by_admin$
> >> > DECLARE
> >> > fire BIGINT;
> >> > BEGIN
> >> > --fire = NEW.fire_code;   -- <-- RAIZ DO PROBLEMA
> >> > IF (TG_OP = 'DELETE') THEN
> >> > DELETE FROM sch_temp.resumo
> >> > WHERE fir_code = fire;
> >> > ELSIF (TG_OP = 'UPDATE') OR (TG_OP = 'INSERT') THEN
> >> > --DELETE FROM sch_temp.resumo
> >> > --WHERE fir_code = fire;
> >> > INSERT INTO sch_temp.resumo(fir_code, adm_code, adm_area) (
> >> > SELECT t2.fir_code, t1.adm_code,
> >> > sum(ST_Area(ST_Intersection(t1.geom,t2.geom)))
> >> > FROM sch_temp.municipios AS t1, sch_temp.incendios AS t2
> >> > WHERE (t1.geom && t2.geom)
> >> > AND ST_Intersects(t1.geom,t2.geom)
> >> > GROUP BY t2.fir_code, t1.adm_code);
> >> > END IF;
> >> > RETURN NULL;
> >> > END;
> >> > $fire_by_admin$ LANGUAGE plpgsql;
> >> >
> >> > CREATE TRIGGER funcao_incendios
> >> > AFTER INSERT OR UPDATE OR DELETE ON sch_temp.incendios
> >> > FOR EACH ROW EXECUTE PROCEDURE funcao_incendios();
> >> >
> >> > -- insert
> >> > INSERT INTO sch_temp.incendios(fir_code, geom) VALUES(1,
> >> > ST_GeomFromText('SRID=23030;POLYGON((726000 4429000,729000
> >> > 4429000,729000
> >> > 4426000,726000 4426000,726000 4429000))'));
> >> > SELECT * FROM sch_temp.resumo;
> >> >
> >> > -- resultado observado e esperado
> >> > /*fir_code,adm_code,adm_area
> >> > 1;1;101;4500000
> >> > 2;1;102;4500000*/
> >> >
> >> > -- update
> >> > UPDATE sch_temp.incendios SET geom =
> >> > ST_GeomFromText('SRID=23030;POLYGON((727000 4429000,729100
> >> > 4429000,729100
> >> > 4427000,727000 4429000))') WHERE gid = 1;
> >> > SELECT * FROM sch_temp.resumo;
> >> >
> >> > -- resultado observado
> >> > /*fir_code,adm_code,adm_area
> >> > 1;1;101;4500000  <- este registe devia ser eliminado, vem do INSERT
> >> > 2;1;102;4500000  <- este registe devia ser eliminado, vem do INSERT
> >> > 3;1;101;2100000*/
> >> >
> >> > -- resultado esperado
> >> > /*fir_code,adm_code,adm_area
> >> > 3;1;101;2100000*/
> >> >
> >> > -- eliminar todo o anterior
> >> > /*DROP TRIGGER IF EXISTS funcao_incendios ON sch_temp.incendios;
> >> > SELECT DropGeometryColumn('sch_temp','incendios','geom');
> >> > SELECT DropGeometryColumn('sch_temp','municipios','geom');
> >> > DROP TABLE sch_temp.resumo;
> >> > DROP TABLE sch_temp.municipios;
> >> > DROP TABLE sch_temp.incendios;*/
> >> > -----------------------------------------------------
> >> >
> >>
> >>
> >> Não sei se é apenas um erro de digitação mas o campo fire_code em sua
> >> tabela incendios.
> >> Talvez deva ser fir_cod.
> >>
> >> Outro detalhe é que no caso da operação DELETE o campo NEW.fir_code
> >> contém NULL, para sua função ter sentido você precisa se referir a
> >> OLD.fir_code.
> >>
> >> Osvaldo
> >>
> >
> >
> > Sim estava mal, substitui o *fire_code* por *fir_code*.
> >
> > Se ponho assim: ERROR: error de sintaxis en o cerca de «SELECT»
> > *fire = SELECT fir_cod FROM sch_temp.incendios WHERE NEW.geom =
> OLD.geom;*
> >
> > Desta maneira da-me: ERROR:  el registro «old» no ha sido asignado aún
> > *fire = OLD.fir_code;*
> >
> > Não sei como definir o *fir_code* que devem ser eliminados.
> >
>
>
> Para a atribuição utilize SELECT INTO.
>
> Para o segundo ponto você precisa utilizar NEW ou OLD dependendo da
> operação (INSERT, UPDATE ou DELETE) sendo realizada.
>
> Em minha opinião no lugar da variável local fire você deve utilizar
> NEW.fir_code ou OLD.fir_code diretamente nos comandos SQL, após a
> devida identificação da operação sendo tratada.
>
> Osvaldo
>
> :-) já funciona!
obrigado!
ficou assim:
CREATE OR REPLACE FUNCTION funcao_incendios() RETURNS trigger AS
$fire_by_admin$
BEGIN
IF (TG_OP = 'DELETE') THEN
DELETE FROM sch_temp.resumo
WHERE fir_code = OLD.fir_code;
ELSIF (TG_OP = 'UPDATE') OR (TG_OP = 'INSERT') THEN
DELETE FROM sch_temp.resumo
WHERE fir_code = NEW.fir_code;
INSERT INTO sch_temp.resumo(fir_code, adm_code, adm_area) (
SELECT t2.fir_code, t1.adm_code,
sum(ST_Area(ST_Intersection(t1.geom,t2.geom)))
FROM sch_temp.municipios AS t1, sch_temp.incendios AS t2
WHERE (t1.geom && t2.geom)
AND ST_Intersects(t1.geom,t2.geom)
GROUP BY t2.fir_code, t1.adm_code);
END IF;
RETURN NULL;
END;
$fire_by_admin$ LANGUAGE plpgsql;
_______________________________________________
pgbr-geral mailing list
pgbr-geral@listas.postgresql.org.br
https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral

Responder a