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