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

Responder a