2011/3/25, Eloi Ribeiro <[email protected]>: > On Fri, Mar 25, 2011 at 13:57, Osvaldo Kussama > <[email protected]>wrote: > >> 2011/3/25, Eloi Ribeiro <[email protected]>: >> > 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 _______________________________________________ pgbr-geral mailing list [email protected] https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral
