Professional Documents
Culture Documents
15/09/15
Triggers (Disparadores)
En PostgreSQL, los triggers son funciones que pueden ser escritas en cualquier lenguaje
procedural como PL/pgSQL, PL/Tcl, PL/Perl y PL/Python. Actualmente no es posible escribir un
trigger directamente en lenguaje SQL.
Un trigger o disparador es una accin definida en una tabla de la base de datos y ejecutada
automticamente por una funcin programada por el DBA o el programador. Esta accin se
activar, segn se haya definido, cuando se realice un INSERT, un UPDATE un DELETE en la
tabla mencionada.
Un disparador se puede definir de las siguientes maneras:
Para que ocurra ANTES de cualquier INSERT,UPDATE DELETE
Para que ocurra DESPUES de cualquier INSERT,UPDATE DELETE
Para que se ejecute una sola vez por comando SQL (statement-level trigger)
Para que se ejecute por cada fila afectada por un comando SQL (row-level trigger)
Esta es la sintaxis del comando SQL que se utiliza para definir un trigger en una tabla.
CREATE TRIGGER nombre { BEFORE | AFTER } { INSERT | UPDATE | DELETE
[ OR ... ] }
ON tabla [ FOR [ EACH ] { ROW | STATEMENT } ]
Caractersticas y Reglas
A continuacin se mencionan algunas de las caractersticas y reglas ms importantes a
considerar, cuando se defina un trigger y/o se programe un procedimiento almacenado que sea
utilizado por un disparador:
1. El procedimiento almacenado que se vaya a utilizar por el trigger debe definirse e instalarse
antes de definir el propio disparador.
2. Un procedimiento que se vaya a utilizar por un trigger no puede tener argumentos y tiene
que devolver el tipo "trigger".
3. Un mismo procedimiento almacenado se puede utilizar por mltiples triggers en diferentes
tablas.
4. Procedimientos almacenados utilizados por disparadores que se ejecutan una sola vez por
comando SQL (statement-level) tienen que devolver siempre NULL.
Valentn Belisario Domnguez Vera
15/09/15
5. Procedimientos almacenados utilizados por triggers que se ejecutan una vez por fila
afectada por el comando SQL (row-level) pueden devolver una fila de tabla.
6. Procedimientos almacenados utilizados por triggers que se ejecutan una vez por fila
afectada por el comando SQL (row-level) y ANTES de ejecutar el comando SQL que lo
lanz, pueden:
1. Retornar NULL para saltarse la operacin en la fila afectada.
2. devolver una fila de tabla (RECORD)
7. Procedimientos almacenados utilizados por triggers que se ejecutan AFTER de ejecutar el
comando SQL que lo lanz, ignoran el valor de retorno, asi que pueden retornar NULL sin
problemas.
8. En resumen, independendientemente de cmo se defina un trigger, el procedimiento
almacenado utilizado por dicho disparador tiene que devolver bien NULL, bien un valor
RECORD con la misma estructura que la tabla que lanz dicho trigger.
9. Si una tabla tiene ms de un disparador definido para un mismo evento (INSERT, UPDATE,
DELETE), estos se ejecutarn en orden alfabtico por el nombre del trigger. En el caso de
disparadores del tipo BEFORE / row-level, la file retornada por cada disparador, se
convierte en la entrada del siguiente. Si alguno de ellos retorna NULL, la operacin ser
anulada para la fila afectada.
10.Procedimientos almacenados utilizados por disparadores pueden ejecutar sentencias SQL
que a su vez pueden activar otros disparadores. Esto se conoce como disparadores en
cascada. No existe lmite para el nmero de triggers que se pueden llamar pero es
responsabilidad del programador el evitar una recursin infinita de llamadas en la que un
disparador se llame asi mismo de manera recursiva.
Otra cosa que tenemos que tener en cuenta es que, por cada disparador que definamos en una
tabla, nuestra base de datos tendr que ejecutar la funcin asociada a dicho disparador. El uso de
triggers de manera incorrecta inefectiva puede afectar significativamente al rendimiento de
nuestra base de datos. Los principiantes deberian de usar un tiempo para entender cmo
funcionan y as poder hacer un uso correcto de los mismos antes de usarlos en sistemas en
produccin.
15/09/15
TG_WHEN. Tipo de dato text; una cadena de texto con el valor BEFORE o AFTER
dependiendo de como el disparador que est usando la funcin actualmente ha sido definido
TG_LEVEL. Tipo de dato text; una cadena de texto con el valor ROW o STATEMENT
dependiendo de como el disparador que est usando la funcin actualmente ha sido definido
TG_OP. Tipo de dato text; una cadena de texto con el valor INSERT, UPDATE o DELETE
dependiendo de la operacin que ha activado el disparador que est usando la funcin
actualmente.
TG_RELID. Tipo de dato oid; el identificador de objeto de la tabla que ha activado el
disparador que est usando la funcin actualmente.
TG_RELNAME. Tipo de dato name; el nombre de la tabla que ha activado el disparador que
est usando la funcin actualmente. Esta variable es obsoleta y puede desaparacer en el futuro.
Usar TG_TABLE_NAME.
TG_TABLE_NAME. Tipo de dato name; el nombre de la tabla que ha activado el disparador
que est usando la funcin actualmente.
TG_TABLE_SCHEMA. Tipo de dato name; el nombre de la schema de la tabla que ha
activado el disparador que est usando la funcin actualmente.
TG_NARGS. Tipo de dato integer; el nmero de argumentos dados al procedimiento en la
sentencia CREATE TRIGGER.
TG_ARGV[]. Tipo de dato text array; los argumentos de la sentencia CREATE TRIGGER. El
ndice empieza a contar desde 0. Indices invlidos (menores que 0 mayores/iguales que
tg_nargs) resultan en valores nulos.
Ejemplos
Una vez que hemos visto la teoria bsica de disparadores nada mejor que unos cuantos ejemplos
prcticos para ver como se usan y defininen los disparadores en PostgreSQL. (estos ejemplos han
sido comprobados en postgreSQL 9.1 y pgAdmin III v.1.14.2).
1. Ejecute pgAdmin III
Se abrir una ventana como la de la
derecha. Puede observar que es la
versin 9.1 y que hay tres bases de
datos (se usaron en ejercicios
anteriores).
15/09/15
15/09/15
En caso que no aparezca la tabla, seleccione el objeto Tablas con el botn derecho y seleccione
la opcin Refresh. Debera aparecer la tabla.
6. Despus tenemos que crear una funcin en PL/pgSQL para ser usada por nuestro disparador.
Nuestra primera funcin es la ms simple que se puede definir y lo nico que har es devolver el
valor NULL.
Como se dijo en un inicio, un trigger es una accin que se guarda en una tabla, as que puede
corroborar la ejecucin de la sentencia anterior si revisa en el object browser la tabla numeros y
observa el SQL pane
La figura siguiente muestra que como parte de la definicin de la tabla tenemos las columnas de la
tabla numeros ms el trigger que se estableci en este paso.
15/09/15
8. Ahora vamos a definir una nueva funcin un poco ms complicada y un nuevo disparador en
nuestra tabla numeros.
15/09/15
Si bien, slo se introdujeron valores en la columna numero, note que el resto de las columnas
tienen sus propios valores. Esto se debe al
funcionamiento de los triggers y de los stored
procedures - procedimientos almacenados.
15/09/15
15/09/15
16. A continuacin crearemos un disparador nico para las sentencias INSERT, UPDATE y
DELETE. Este nuevo disparador
utilizar una nueva funcin a la que
llamaremos proteger_y_rellenar_datos
(figura de la izquierda) en la que
tendremos que tomar en cuenta qu
tipo de comando ha activado el
disparador, si queremos retornar el
valor correcto. Para ello utilizaremos la
variable TG_OP.
15/09/15
10
15/09/15
22. Por ltimo, intente hacer la eliminacin de un registro, puede ser cualquiera aunque se
escoger el que tiene el valor de 4.
11
15/09/15
Todas las actividades realizadas tambin se pueden hacer en modo comando en la herramienta
denominada SQL shell que es uno de los programas del PostgreSQL
Cuando se ejecuta el SQL shell aparecer una ventana similar a la de arriba, en la que se deber
aceptar las propuestas que hace.
La aplicacin le informa si se desea conectar al Server [localhost], presione [enter].
Luego cuestiona si se desea conectar con la base de datos [postgres], presione [enter].
Le pregunta si el puerto es [5432], presione [enter].
Finalmente se le introduce el username [postgres], presione [enter].
Si la contrasea del username, la tiene guardada la aplicacin, ya no se solicitar; pero si no tiene
la contrasea guardada, entonces hay que teclearla y presionar [enter].
Introduzca los comandos mostrados en la siguiente figura
12
15/09/15
El primero es para crear la base de datos test002 y el segundo es para hacer la conexin a dicha
base de datos. El lenguaje plpgsql est instalado por default. En caso que no sea as, se introduce
el siguiente comando
Ahora se proceder a crear la tabla numeros.
Se escribe la funcin para actualizar las columnas cuadrado, cubo, raiz2 y raiz3
13
15/09/15
14
15/09/15
Si despliega nuevamente el contenido de la tabla, se mostrar sin cambio alguno ya que el trigger
proteger_datos est evitando que se borre algo de la tabla.
Si compara esta parte con la seccin que se hizo en el pgAdmin III, observar que son las mismas
instrucciones slo que ahora se est trabajando en modo comando.
Para salir del modo comando se introduce el comando \q
ACTIVIDAD1: Se deja como actividad al estudiante realizar a partir del paso 15 en la que se
eliminan los dos triggers, se crea la funcin combinada proteger_y_rellenar_datos con su trigger
respectivo, y volver a revisar el funcionamiento insertando nuevos valores e intentando borrar
algn registro.
ACTIVIDAD2: La puede realizar en modo grfico (pgAdmin III) o en modo comandos (SQL shell).
1. Cree una base de datos llamada facturas y una tabla que se llame detalle_fac que tenga
los campos relativos a cdigo de producto, precio unitario, cantidad de piezas, subtotal
(resultado de multiplicar la cantidad de piezas por el precio unitario), iva (resultado de
15
15/09/15
multiplicar el subtotal por el 16%), total (suma del subtotal y el iva). Haga que la llave
primaria sea la columna cdigo de producto.
2. Usted debe seleccionar los tipos de datos ms apropiados para cada campo o columna.
3. Inserte los siguientes datos slo en las columnas relativas a cdigo de producto, cantidad
de piezas y precio unitario.
4. Primer registro: 100, 2 y $10.50
5. Segundo registro: 110, 3 y $3.33
6. Haga un desplegado de todos los campos para ver la informacin de la tabla. Slo deben
aparecer datos en las tres primeras columnas y primeros dos registros.
7. Cree la(s) funcion(es) y trigger(s) que necesite para calcular el subtotal, el iva y el total.
8. Inserte los siguientes datos slo en las columnas relativas a cantidad de piezas y precio
unitario.
9. Tercer registro: 120, 5 y $1.50
10. Cuarto registro: 130, 4 y $2.25
11. Haga un desplegado de todos los campos para ver la informacin de la tabla. Ahora deben
aparecer datos en cuatro registros. Los primeros dos slo deben tener datos en las
primeras tres columnas. Los siguientes dos registros deben tener datos en todas las
columnas.
Fuente:
http://www.postgresql.org.es/node/301 , artculo del 11/06/2009, por usuario: rafaelma
revisada en Agosto/2012
16