Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
Los triggers o disparadores de PostgreSQL son una de sus funcionalidades ms tractivas.Ante una determinada operacin (INSERT, UPDATE O DELETE) provocan la ejecucin de una funcin en nuestra base de datos. Si esto lo usamos en conjuncin con PostGIS, nos permite tener tablas en las que el manejo de datos espaciales sea sencillo. La documentacin sobre los triggers es prolija y yo, sobre todo por falta de conocimiento profundo, no quisiera extenderme demasiado e ir al grano.
Ahora bien, existe un problema y es que que PostgreSQL + PostGIS no almacenan la informacin espacial de una manera directamente interpretable por el usuario, como unos valores numricos de latitud y longitud, por ejemplo, ni los programas leen la informacin de bases de datos PostGIS de esa manera, sino que para ello utilizan un formato descrito por el Open Geospatial Consortium denominado WKB (Well-Known Binary) que es el formato en el que las bases de datos almacenan la informacin espacial. El WKB tiene un hermano mellizo que es el WKT (Well-Known Text) que es la representacin digamos humanamente entendible del objeto que almacenamos como WKB. He hecho mencin al objeto porque hay diferentes tipos de objetos espaciales. Los ms habituales y que en los que pensaremos inmediatamente son el punto y la lnea pero tenemos tambin multilneas, polgonos, multipolgonos, multipuntos y cada uno de ellos con su SRID o sistema de coordenadas asociado. Por eso, una tabla que almacene un objeto de tipo punto no tiene una columna para latitud y otra para longitud, sino que tiene una nica columna que almacena el objeto. Para almacenarlo, PostGIS proporciona unas funciones que permiten la creacin de los objetos a partir de sus coordenadas, tipo de objeto, SRID, etc. Pero es probable que a nosotros nos interese recuperar sin mayor problema las coordenadas numricas de nuestros puntos o lneas o, simplemente, que podamos interactuar con mayor facilidad con nuestra base de datos. Es ms fcil introducir los datos numricamente, tal y como los podemos tomar en el barco que tenindonos que acordar cada vez de pasar la funcin con los parmetros adecuados.Y nos puede interesar, para facilitar luego medidas de distancia, etc o la representacin de los lances en un mapa, disponer de nuestro lance como un objeto de tipo lnea en lugar de de puntos separados. Y aqu es donde aparecen los triggers.
aadindoles stas mediante una funcin de PostGIS llamada (muy original no es, pero s prctico y lgico, como debe ser) AddGeometryColumn(), La creacin de la tabla es trivial, ahora bien hemos de tener en cuenta que necesitaremos, para cada uno de los puntos involucrados en la creacin de nuestro objeto espacial (uno si es un punto, dos si es una lnea) , dos columnas; una almacenar la longitud y la otra la latitud.
DROP TABLE IF EXISTS lances; CREATE TABLE lances( campana varchar(20), lance int,
1 DROP TABLE IF EXISTS lances; 2 CREATE TABLE lances( 3 campana varchar(20), 4 lance int, 5 lar_lat numeric(12,8), 6 lar_lon numeric(12,8), 7 fir_lat numeric(12,8), 8 fir_lon numeric(12,8), 9 vir_lat numeric(12,8), 10 vir_lon numeric(12,8), 11 fin_lat numeric(12,8), 12 fin_lon numeric(12,8), 13 );
1 AddGeometryColumn(varchar tabla, varchar columna, int srid, int tipo, int dimension) Donde:
tabla es el nombre de la tabla a la que vamos a aadir la columna, columna es el nombre de la columna a aadir,
srid es el sistema de referecia de coordenadas del elemento que vamos a aadir. Para los que usamos el sistema WGS84 (que es el SRID de las coordenadas que proporcionan los GPS habitualmente, o al menos las sentencias NMEA a las que tenemos acceso), este valor es 4326. Para otros SRID es buena idea buscar en www.spatialreference.org. tipo es el tipo de elemento a insertar (linea, punto) dimension es el numero de dimensiones del mismo (en nuestro caso, 2)
Con esto y un poquito de ganas, creamos nuestras columnas para los puntos y la lnea:
2);
1 SELECT AddGeometryColumn( 'lances', 'lar_punto', 4326, 'POINT', 2); 2 SELECT AddGeometryColumn( 'lances', 'fir_punto', 4326, 'POINT', 2); 3 SELECT AddGeometryColumn( 'lances', 'vir_punto', 4326, 'POINT', 2); 4 SELECT AddGeometryColumn( 'lances', 'fin_punto', 4326, 'POINT', 2); 5 SELECT AddGeometryColumn( 'lances', 'lance_linea', 4326, 'LINESTRING', 2); Notacion Actual
SELECT AddGeometryColumn('ch01', 'fastfoods','geom', 2163, 'POINT',2); Consulta inserter datos
insert into ch01.lances (campana,lance,lar_lat,lar_lon,fir_lat,fir_lon,vir_lat,vir_lon,fin_lat,fin_lon) values ('Uno',4,100.35,200.4,305.2,401.3,500.4,600.2,700.1,800.2); Ahora ya viene la parte ms delicada y es la creacin del trigger.
En la segunda fase, asociaremos ese trigger a nuestra tabla en la base de datos. Esta es, al menos lxicamente, la verdadera creacin del trigger. El cdigo para crear la funcin es el siguiente:
CREATE OR REPLACE FUNCTIO $posiciones_lance$ DECLARE BEGIN
1 CREATE OR REPLACE FUNCTION posiciones_lance() RETURNS TRIGGER AS 2 $posiciones_lance$ 3 DECLARE 4 BEGIN 5 NEW.ini_punto:=ST_SetSRID(ST_MakePoint(NEW.ini_lon,NEW.lar_lat),4326); 6 NEW.lar_punto:=ST_SetSRID(ST_MakePoint(NEW.lar_lon,NEW.lar_lat),4326); 7 NEW.vir_punto:=ST_SetSRID(ST_MakePoint(NEW.vir_lon,NEW.vir_lat),4326); 8 NEW.fin_punto:=ST_SetSRID(ST_MakePoint(NEW.fin_lon,NEW.lar_lat),4326); 9 NEW.lance_linea:=ST_Makeline(NEW.lar_punto,NEW.vir_punto); 10 RETURN NEW; 11 END; 12 $posicion_lance$ LANGUAGE plpgsql; Aparte de las lneas que crean formalmente la sentencia, las que nos interesa conocer cmo funcionan son las del tipo
NEW.XXX_punto:=ST_SetSRID(
NEW.XXX_punto:=ST_SetSRID(ST_MakePoint(NEW.XXX_lon,NEW.XXX_lat),4326 );
Bsicamente, lo que le decimos a nuestro servidor es que cuando al ejecutar el trigger se le pase a la funcin que vamos a crear el registro que se inserta o actualiza, el NUEVO valor de la columna XXX_punto ser el resultado de:
Crear un punto mediante la funcin ST_MakePoint() de PostGIS. Asignar un SRID a ese punto, en nuestro caso el 4326 (WGS84)
Fijaos en lo de NEW, porque volveremos sobre ello ms adelante. Una vez creado los puntos y aprovechando que stos tienen ya asignado su SRID, mediante la sentencia
NEW.lance_linea:=ST_Makeline(
1 NEW.lance_linea:=ST_Makeline(NEW.lar_punto,NEW.vir_punto); Creamos la lnea que unir los puntos de largado y virada. Ahora, lo que hace el resto de la funcin
RETURN NEW; END; $posicion_lance$ LANGUAGE p
1 RETURN NEW; 2 END; 3 $posicion_lance$ LANGUAGE plpgsql; es retornar el registro NUEVO , indicar que la funcin termina y cerrar la declaracin de la funcin. Ahora, como dijimos antes, viene la segunda fase y es la declaracin del trigger. Esto lo hacemos mediante las siguientes sentencias:
CREATE TRIGGER posicion_lanc BEFORE INSERT OR UPDATE ON FOR EACH ROW EXECUTE PR
1 CREATE TRIGGER posicion_lance 2 BEFORE INSERT OR UPDATE ON lances 3 FOR EACH ROW EXECUTE PROCEDURE posicion_lance(); Os acordis de lo que os dije antes acerca de los registros NUEVOS? Pues bien, si os fijis en la parte de BEFORE INSERT OR UPDATE IN lances , lo que decimos aqu es que antes de que se inserte o actualice el nuevo registro ejecute la funcin que hemos creado sobre cada tupla que se inserte. Por tanto, las variables sobre las que operamos son las columnas de cada tupla, y nos referimos a ellas con NEW.nombre_de_columna, con lo cual, para que quede insertada correctamente la columna de geometra nos referimos a ella en la funcin como NEW igualmente. Ahora ya tenemos nuestra tabla lances habilitada para los datos espaciales y, lo que es mejor an, podemos introducir las coordenadas de los mismos sin necesidad de
emplear funciones de PostGIS en cada una de nuestras consultas de insercin o actualizacin de datos. Espero que el artculo os sea de utilidad!!!