Está en la página 1de 15

DESENCADENADORES (TRIGGERS) Y CURSORES.

Introducción

En contenidos tratados anteriormente se estudió cómo crear objetos de tipo vistas y


funciones para una base de datos. Se veía cómo estos nuevos objetos facilitaban el
trabajo con la base de datos y la interacción con los datos dentro de las tablas.
El lenguaje PL/pgSQL permite la creación de otros tipos de objetos denominados
desencadenadores (triggers en inglés) como vía de ejecutar funciones de forma
automática dentro del gestor de base de datos, sin necesidad de que sea el usuario
quien mande a ejecutar una operación determinada.
Otro elemento que se trabajó fue cómo devolver un conjunto de tuplas en una vista,
que cumplieran una condición determinada. ¿Qué pasa si de todas esas tuplas
resultantes sólo interesan determinados campos? Para ello se necesita un mecanismo
que trabaje con una fila o un pequeño bloque de filas cada vez. Los cursores son una
extensión de los conjuntos de resultados que proporcionan dicho mecanismo.
A continuación se abordan algunos de los elementos importantes sobre estas nuevas
funcionalidades: desencadenadores (Triggers) y cursores.

Desarrollo
TRIGGER
Se han visto las ventajas que la funciones proporcionan al simplificar acciones en una
base de datos. Pero estas acciones requieren la intervención de una persona
encargada de ejecutar las funciones cuando se requiera de su actuación. Los triggers
al contrario, son funciones que se ejecutan de forma automática en respuesta a ciertos
eventos que ocurren en la base de datos.
Un trigger es una acción en cadena que empieza cuando un evento específico ocurre
sobre una tabla específica.

¿Cuándo entra en vigor un trigger?


 Antes o después de una inserción (INSERT).
 Antes o después de una actualización (UPDATE).
 Antes o después de una eliminación (DELETE).
 Antes o después de la eliminación de todos los datos de una tabla
(TRUNCATE).

Nota: TRUNCATE es un evento a través del cual se pueden eliminar todas las filas de
una tabla o de un conjunto de tablas.
Su sintaxis es la siguiente:
TRUNCATE [ TABLE ] [ ONLY ] name [, ... ]
[ RESTART IDENTITY | CONTINUE IDENTITY ] [ CASCADE | RESTRICT ]
Si se especifica ONLY solo la tabla indicada en el comando es truncada, sino serán
truncadas además las tablas descendientes (si las hay).
Si se especifica RESTART IDENTITY se reinician automáticamente los campos
secuenciales de la tabla truncada. Si se especifica CONTINUE IDENTITY no se
producen cambios en los valores de las secuencias, este es el valor por defecto.
Si se especifica CASCADE, serán truncadas además de la tabla indicada, todas
aquellas que hagan referencia a través de una llave foránea a algún campo de la tabla
especificada en el comando.
Si se especifica RESTRICT, la tabla indicada en el comando no será truncada mientras
exista alguna otra tabla que haga referencia a ella a través de una llave foránea. Esta
es la opción por defecto.

El uso de los triggers está muy vinculado con la realización de acciones para auditar y
monitorear la actividad de cambio de datos dentro de una base de datos. Permiten
validar datos, cambiando o negando acciones como INSERT, UPDATE y DELETE en
una tabla. Además, su funcionalidad les permite preservar la consistencia y claridad de
los datos ejecutando acciones relacionadas con otras tablas.

Ventajas de los triggers:


 Pueden consultar otras tablas e incluir instrucciones SQL complejas.
 Son especialmente útiles para exigir reglas o requisitos complejos.
 Son útiles para exigir la integridad referencial, que conserva las relaciones
definidas entre tablas cuando se agregan, actualizan o eliminan filas en esas
tablas.
 Son automáticos, se activan al efectuarse modificaciones en los datos de la
tabla, como una entrada manual o una acción de la aplicación.
 Pueden realizar cambios en cascada a través de tablas relacionadas de la base
de datos, al igual que cuando se define las cláusulas ON DELETE y ON
UPDATE al definir restricciones de integridad referencial al crear tablas.
 Pueden exigir restricciones más complejas que las definidas con restricciones
CHECK.
 Ofrecen un mayor control sobre la Base de Datos.

Definición de los triggers:


La definición de un trigger consta de dos partes:
1. La definición de la función asociada al trigger, que es la que ejecuta la acción en
respuesta al evento (INSERT, UPDATE, DELETE, TRUNCATE).
2. La definición formal de trigger que indicará:
a) De qué tabla se esperarán los eventos.
b) A qué tipo de evento se responderá (puede responder a más de un evento, se
separan los eventos con el operador lógico OR).
Funciones Tipo Trigger:
Una función tipo trigger es similar a una función normal, salvo por algunos detalles:
 El tipo de retorno ya no es un tipo normal de PostgreSQL, sino el tipo especial
trigger.
 Dependiendo de las acciones del trigger, el parámetro en el comando RETURN
puede variar y es obligatorio que se retorne algo siempre.

Ejemplo:

CREATE OR REPLACE FUNCTION name ( [ [ argmode ] [ argname ] argtype [, ...] ] )


[ RETURNS trigger ]
AS $$
DECLARE
Variable;
Variable;
BEGIN
sentencia;
END;
$$
LANGUAGE ‘plpgsql’;

Luego de elaborada la función trigger, se debe definir formalmente el trigger de este


modo:

CREATE OR REPLACE TRIGGER nombre_trigger


[ AFTER | BEFORE ] [ INSERT | UPDATE | DELETE | TRUNCATE]
ON nombre_tabla
FOR EACH [ROW | STATEMENT]
EXECUTE PROCEDURE function;

Argumentos:
nombre_trigger: Es el nombre del desencadenador.

[ AFTER | BEFORE ]: Define el momento en que el desencadenador entra en acción.


Puede ser BEFORE (antes) o AFTER (después), para indicar que el disparador se
ejecute antes o después que la sentencia que lo activa.

[ INSERT | UPDATE | DELETE ]: Indica la clase de sentencia que activa al disparador.


Puede ser INSERT, UPDATE o DELETE. Por ejemplo, un disparador BEFORE para
sentencias INSERT podría utilizarse para validar los valores a insertar.
nombre_tabla: Nombre tabla a la que está asociado el disparador.

FOR EACH [ROW | STATEMENT]: Para cada fila o para cada sentencia.

EXECUTE PROCEDURE function: Es la sentencia que se ejecuta cuando se activa el


disparador. Si se desean ejecutar múltiples sentencias, deben colocarse entre BEGIN y
END.

Los desencadenadores pueden incluir cualquier número y clase de instrucciones SQL.


Un desencadenador está diseñado para comprobar o cambiar los datos; no debe
devolver datos al usuario.

PostgreSQL también maneja algunas variables al momento de ejecutar un trigger,


algunas de estas son:

NEW: Variable compuesta que almacena los nuevos valores de la tupla que se está
modificando.

OLD: Variable compuesta que almacena los valores antiguos de la tupla que se está
modificando.

TG_OP: Variable tipo string que indica qué tipo de evento está ocurriendo (INSERT,
UPDATE, DELETE).

TG_ARGV: Variable tipo arreglo que almacena los parámetros de la función del trigger,
los cuales se pueden acceder de la forma TG_ARGV[0], TG_ARGV[1], …
TG_ARGV[n].

TG_NAME: Variable que contiene el nombre del trigger ejecutado actualmente.

TG_WHEN: Variable tipo texto, que contiene: BEFORE o AFTER, dependiendo de la


definición del trigger.

TG_TABLE_NAME: Variable que almacena el nombre de la tabla que provocó la


invocación del trigger.

Revisar el siguiente ejemplo:

Sea la tabla Producto en la base de datos:

PRODUCTO (producto_id, nombre, tipo, cantidad, precio_compra, precio_venta).


La tabla PRODUCTO tiene la capacidad de almacenar la información más actual e
importante de los productos para una tienda de computadoras, pero hay otro tipo de
información que no es capaz de almacenar, que es la información del cambio de datos.
La tabla PRODUCTO no tiene memoria de los cambios que han sufrido sus tuplas, de
manera que si alguien cambia el precio de venta de un artículo no hay forma de
obtener el precio anterior. Si alguien borra un artículo, tampoco se sabe qué artículo ha
sido borrado ni por quién.
Esto conlleva a una de las grandes áreas de utilización de los triggers, la auditoría de
tablas.

Entonces, ¿cuáles son las acciones que se deben realizar con un trigger?
 Se necesita llevar un registro de todos los cambios relevantes en la tabla
PRODUCTO, comenzando por tener un seguimiento de los cambios en los
precios de los productos.

Se debe crear una tabla que almacene los cambios de precio en la tabla PRODUCTO,
la cual se llamará PRODUCTO_ACTUALIZADO.

PRODUCTO_ACTUALIZADO (producto_id, nombre, precio_anterior,


precio_actualizado, autor, fecha_cambio).

La función que ejecutará el trigger quedaría de la siguiente forma:

CREATE FUNCTION producto_actualizado_tri()


RETURN trigger
AS $$
BEGIN
IF (NEW.precio_venta <> OLD.precio_venta) THEN
INSERT INTO PRODUCTO_ACTUALIZADO VALUES (OLD.producto_id,
OLD.nombre, OLD.precio_venta, NEW.precio_venta, current_user,
current_date);
END IF;
RETURN NULL;
END;
$$
Language 'plpgsql';

Se está insertando para la tabla PRODUCTO_ ACTUALIZADO los datos asociados a


los cambios realizados en la tabla PRODUCTO.
Ahora se crea el trigger que llamará la función anterior:

CREATE TRIGGER actualizar_producto


AFTER UPDATE ON PRODUCTO
FOR EACH ROW
EXECUTE PROCEDURE producto_actualizado_tri();

Al trigger se le especifica que siempre se ejecutará después que se actualice la tabla


PRODUCTO, de esta forma siempre que se actualice el precio de venta en la tabla
PRODUCTO, el precio de venta antiguo y nuevo se insertarán en la tabla
PRODUCTO_ACTUALIZADO.
Los triggers son objetos de la BD, por lo tanto, además del CREATE TRIGGER se les
puede aplicar el ALTER TRIGGER para modificar un desencadenador y el DROP
TRIGGER para eliminarlo. El hecho de eliminar un desencadenador no afecta a la tabla
ni a los datos en los que está basado. Si se elimina una tabla, se eliminarán
automáticamente todos los desencadenadores asociados a ella.
Ya se han visto todas las ventajas de los triggers, a continuación se listan sus
desventajas.

Desventajas de los Triggers:


 Hay que definir con anticipación la tarea que realizará.
 Peligro de pérdida en reorganizaciones.
 No se pueden utilizar en tablas temporales.

Tipos de Triggers especiales:


Existen dos tipos de disparadores que son especiales debido a los beneficios que
brindan y que constituyen funcionalidades nuevas del Postgres 9.0, estos son:
disparadores de columnas y disparadores condicionales.

Disparadores de columnas: Los mismos son ejecutados cuando una o varias


columnas definidas por el usuario son actualizadas. Este tipo de disparador le permite
al desarrollador no tener que utilizar la lógica condicional y la comparación de valores
en las funciones usadas por un disparador.

Para definir un trigger de columna se le añade a la sintaxis general la cláusula OF,


donde se especifica la columna a monitorear, quedando la sintaxis de la siguiente
forma:

CREATE TRIGGER nombre_trigger


[ AFTER | BEFORE ] UPDATE
OF nombre_columna ON nombre_tabla
FOR EACH [ROW | STATEMENT]
EXECUTE PROCEDURE function;

Se debe tener en cuenta que los triggers a nivel de columna sólo se pueden aplicar a
las operaciones de tipo UPDATE, incluso si un trigger se dispara por más de un evento
estos deberán ser separados obligatoriamente. No tendría sentido usar INSERT en
este tipo de disparadores, ya que al ejecutar esta sentencia todas las columnas son
afectadas; así como en el caso del DELETE tampoco se utilizaría, ya que este se aplica
directamente sobre una fila y no sobre las columnas.

Ejemplo: En este ejemplo se ejecutará el procedimiento mi_function() si la columna


nombre de la tabla Producto es modificada para alguna de sus filas.

CREATE TRIGGER nombre_trigger


BEFORE UPDATE
OF nombre ON producto
FOR EACH ROW
EXECUTE PROCEDURE mi_function();

Disparadores WHEN (condicionales): Con este tipo de disparador se puede


especificar una condición en la propia definición del disparador. Un trigger condicional
solo se activará si la condición definida durante su creación se cumple. De esta manera
el desarrollador se ahorra el tener que usar una condición IF...THEN dentro del mismo.
Esto brinda reducir considerablemente el número de disparadores a ejecutar, lo que
conlleva a un mejor rendimiento y la disminución del uso de CPU en el servidor de BD.

Para definir un trigger condicional se le añade a la sintaxis general la cláusula WHEN,


quedando la sintaxis de la siguiente forma:

CREATE TRIGGER nombre_trigger


[ AFTER | BEFORE ] [ INSERT | UPDATE | DELETE ]
ON nombre_tabla
FOR EACH [ROW | STATEMENT]
WHEN (condición)
EXECUTE PROCEDURE function;

Condición: Es una expresión booleana que se tiene que verificar para que se ejecute
el trigger.

Ejemplo: En este ejemplo se resuelve la misma problemática del ejemplo anterior, pero
utilizando un trigger condicional.
CREATE TRIGGER disparador1 BEFORE UPDATE
ON producto
FOR EACH ROW
WHEN (OLD.nombre IS DISTINCT FROM NEW.nombre) EXECUTE PROCEDURE
mi_function();

CURSORES
Las operaciones de una base de datos relacional actúan en un conjunto completo de
filas. El conjunto de filas que devuelve una instrucción SELECT está compuesto por
todas las filas que satisfacen las condiciones de la cláusula WHERE de la instrucción.
Este conjunto completo de filas que devuelve la instrucción se conoce como el conjunto
de resultados. Las aplicaciones no siempre pueden trabajar de forma efectiva con el
conjunto de resultados completo si lo toman como una unidad. Estas aplicaciones
necesitan un mecanismo que trabaje con una fila o un pequeño bloque de filas cada
vez. Precisamente los cursores representan consultas SELECT de SQL que devuelven
más de un resultado y que permiten el acceso a cada fila de una consulta.

Los cursores amplían el procesamiento de los resultados de una consulta porque:


 Permiten situarse en filas específicas del conjunto de resultados.
 Recuperan una fila o bloque de filas de la posición actual en el conjunto de
resultados.
 Aceptan modificaciones de los datos de las filas en la posición actual del
conjunto de resultados.
 Aceptan diferentes grados de visibilidad para los cambios que realizan otros
usuarios en la información de la base de datos que se presenta en el conjunto
de resultados.

Los cursores se utilizan principalmente en procedimientos almacenados o funciones,


desencadenadores y secuencias de comandos de SQL, a fin de dejar disponible el
contenido de un conjunto de resultados para otras instrucciones SQL.

Procesamiento de los Cursores


Los cursores se procesan en 4 pasos:
1. Declarar el cursor
2. Abrir el cursor. Tras abrir el cursor, el puntero del cursor señalará a la primera
fila (si existe).
3. Procesar el cursor. La instrucción FETCH permite recorrer el cursor registro a
registro hasta que el puntero llegue al final (hasta que el cursor esté vacío). La
instrucción MOVE también puede ser utilizada en el procesamiento del cursor,
permite posicionarse en una fila específica de la consulta.
4. Cerrar el cursor.

Declarar el Cursor
Sintaxis:
DECLARE
cursor_name CURSOR FOR select_statement;

Pueden definirse varios cursores en una rutina, pero cada cursor en un bloque debe
tener un nombre único.

Argumentos:
cursor_name: Especifica el nombre del cursor.

select_statement: Es una instrucción SELECT estándar que define el conjunto de


resultados del cursor.

Ejemplo:
DECLARE
curs1 refcursor;
curs2 CURSOR FOR SELECT * FROM empleado;

Los dos cursores declarados anteriormente tienen el tipo de datos refcursor, pero el
primer cursor (curs1) puede ser usado para cualquier consulta, mientras que el
segundo es específico para la consulta SELECT * FROM empleado.
Comandos para el trabajo con cursores
 OPEN cursor

Esta sentencia abre el cursor, lo que significa:


1. Reservar memoria suficiente para el cursor.
2. Ejecutar la sentencia SELECT a la que se refiere el cursor.
3. Colocar el puntero antes de la primera fila.

 FETCH [ direction { FROM | IN } ] cursor INTO target;

La sentencia FETCH es la encargada de recorrer el cursor e ir procesando los valores


del mismo. Cada vez que se ejecuta el comando FETCH, se obtiene la próxima fila
correspondiente en el sentido que se especifica en la opción direction. Esta instrucción
permite además almacenar el contenido de la fila a la que apunta actualmente el
puntero en la lista de variables indicada en target, que tienen que tener el mismo
dominio que las columnas representadas en el cursor. Cuando se necesita procesar
cada fila del cursor, esta instrucción se coloca dentro de un bucle.

Esta instrucción cuenta con una opción direction que indica la dirección del recorrido,
que puede ser: NEXT, PRIOR, FIRST, LAST, ABSOLUTE count, RELATIVE count,
FORWARD o BACKWARD. La omisión de esta cláusula implica que el gestor asuma
por defecto el valor NEXT para la misma.

NEXT: Selecciona la fila siguiente.

PRIOR: Selecciona la fila anterior.

FIRST: Selecciona la primera fila de la consulta (es lo mismo que: ABSOLUTE 1).

LAST: Selecciona la última fila de la consulta (es lo mismo que: ABSOLUTE -1).

ABSOLUTE count: Selecciona la n-ésima fila de la consulta. Si count es negativo se


selecciona la n-ésima fila contando a partir de la última.

RELATIVE count: Selecciona la n-ésima fila que sigue a la fila actual. Si count es
negativo se selecciona la n-ésima fila que precede a la fila actual. RELATIVE 0
selecciona la fila actual.

FORWARD: Selecciona la fila siguiente (lo mismo que NEXT).

BACKWARD: Selecciona la fila anterior (lo mismo que PRIOR).


cursor: Nombre de un cursor abierto.

target: Listado de variables donde se almacenará la fila a la que apunta el cursor.

Ejemplos:
FETCH curs1 INTO rowvar;
FETCH curs2 INTO foo, bar, baz;
FETCH LAST FROM curs3 INTO x, y;
FETCH RELATIVE -2 FROM curs4 INTO x;
FETCH cursorProvincias INTO v_nombre, v_poblacion;

Una instrucción FETCH lee una sola fila y su contenido lo almacena en variables. Por
ello se requiere usar bucles cuando se quieren procesar un conjunto de filas de la
consulta asociada al cursor:

LOOP
FETCH cursorProvincias INTO (v_nombre, v_poblacion);
EXIT WHEN... --aquí se pondría la condición de salida...
--instrucciones de proceso de los datos del cursor
END LOOP;

Nota: Si sólo se quisieran mostrar los valores de la consulta asociada al cursor no hay
necesidad de utilizar la cláusula INTO.

Ejemplo:
FETCH ALL IN funccursor – Muestra todas las filas de la consulta asociada al cursor
funccursor.

 CLOSE cursor

Al cerrar el cursor se libera la memoria que ocupa y se impide su procesamiento.


Tras cerrar un cursor este podría ser abierto de nuevo.

 MOVE [ direction { FROM | IN } ] cursor

Permite al usuario mover la posición del cursor un número específico de


filas. MOVE funciona como el comando FETCH, pero sólo posiciona el cursor y no
devuelve filas.
La opción direction, al igual que en comando FETCH, indica la dirección del recorrido,
que puede ser: NEXT, PRIOR, FIRST, LAST, ABSOLUTE count, RELATIVE count,
ALL, FORWARD [ count | ALL ], or BACKWARD [ count | ALL ]

A continuación se explican aquellos que no se mencionaron anteriormente:

ALL: Selecciona todas las filas siguientes (es lo mismo que FORDWARD ALL).

FORWARD [ count | ALL ]: En el caso de count, selecciona las n filas siguientes. En el


caso de ALL selecciona todas las filas siguientes.

BACKWARD [ count | ALL ]: En el caso de count, selecciona las n filas anteriores. En


el caso de ALL selecciona todas las filas anteriores.

Ejemplos:
MOVE curs1;
MOVE LAST FROM curs3;
MOVE RELATIVE -2 FROM curs4;
MOVE FORWARD 2 FROM curs4;

 CURRENT OF

Cuando el cursor se posiciona en una fila de la tabla, la fila puede ser actualizada o
borrada. La sintaxis para ello es la siguiente:

UPDATE table SET ... WHERE CURRENT OF cursor;


DELETE FROM table WHERE CURRENT OF cursor;

Atributos de los Cursores


 IS OPEN: Devuelve verdadero si el cursor ya está abierto.

Ejemplo:
cursorProvincias IS OPEN;

 NOT FOUND: Devuelve verdadero si la última instrucción FETCH no devolvió


ningún valor.

Ejemplo:
BEGIN
OPEN cursorProvincias;
LOOP
FETCH cursorProvincias INTO v_nombre,v_poblacion;
EXIT WHEN NOT FOUND;
END LOOP;
CLOSE cursorProvincias;
END;

En el ejemplo anterior se recorre el cursor hasta que el FETCH no devuelve ninguna


fila.

 FOUND: Devuelve verdadero si el último FETCH devolvió una fila.

Cursores con parámetros:


En muchas ocasiones se podría desear que el resultado de un cursor dependa de una
variable. Por ejemplo al presentar una lista de personal, hacer que aparezca el cursor
de un determinado departamento y puesto de trabajo.
Para hacer que el cursor varíe según esos parámetros, se han de indicar los mismos
en la declaración del cursor. Para ello se pone entre paréntesis su nombre y tipo tras el
nombre del cursor en la declaración.

Ejemplo:
DECLARE
cur_personas CURSOR (dep NUMBER, pue VARCHAR2 (20)) FOR
SELECT nombre, apellidos
FROM empleados
WHERE departamento=dep AND puesto=pue;
BEGIN
OPEN cur_personas (12,’administrativo’);
.....
CLOSE cur_personas;
END
Es al abrir el cursor cuando se indica el valor de los parámetros, lo que significa que se
puede abrir varias veces el cursor y que éste obtenga distintos resultados dependiendo
del valor del parámetro.

Utilización del ciclo FOR para iterar sobre los resultados de un cursor:

La conocida estructura repetitiva FOR, también puede ser utilizada para recorrer cada
uno de los resultados de la consulta a la que se encuentra asociado determinado
cursor. La sintaxis para ello es la que aparece a continuación:

FOR recordvar IN bound_cursorvar [ ( argument_values ) ] LOOP


statements
END LOOP

Se hace necesario que se haya asociado una consulta al cursor cuando el mismo se
declaró. El FOR abre automáticamente el cursor y lo cierra cuando sale del bucle.

Se pueden indicar los parámetros también en el bucle FOR.

Ejemplo
DECLARE
cur_personas CURSOR (dep NUMBER, pue VARCHAR2 (20)) FOR
SELECT nombre, apellidos
FROM empleados
WHERE departamento=dep AND puesto=pue;
BEGIN
FOR r IN cur_personas (12,’administrativo’)
LOOP
.....
END LOOP;
END:

Cursores por referencia:

Cuando se necesita ejecutar una consulta que debe mostrar grandes volúmenes de
datos, es conveniente aplicar cursores en una de sus variantes más eficaces:
Implementar una función que devuelva una referencia a un cursor. Esta aplicación de
los cursores minimiza el tiempo de ejecución de las consultas para la obtención de
volúmenes de datos considerables.

Por ejemplo, supongamos que se tiene la siguiente tabla:


test (id, col)
Se crea la siguiente función, la cual retorna un cursor que apunta al resultado de la
consulta que contiene el listado de valores para la columna col de la tabla test:

CREATE FUNCTION reffunc(refcursor) RETURNS refcursor AS


$$
BEGIN
OPEN $1 FOR SELECT col FROM test;
RETURN $1;
END;
$$
LANGUAGE 'plpgsql';
Para visualizar estos valores basta con ejecutar el siguiente código:
SELECT reffunc('funccursor');
FETCH ALL IN funccursor;

Si se hace un EXPLAIN ANALYZE de las siguientes sentencias, se notará la diferencia


en el rendimiento:
(1) SELECT col FROM test;
(2) SELECT reffunc('funccursor');

Desventajas de los cursores:


 Recuperar una fila del cursor puede resultar en un retraso, lo que se debe al
tiempo necesario para enviar la petición al servidor y esperar los datos.
 Reservan recursos en el servidor, como por ejemplo locks, packages, procesos,
almacenamiento temporal, etc.
 Si un cursor no se cierra de manera correcta, el recurso no será liberado hasta
que la sesión SQL (conexión) sea cerrada. Este desperdicio de recursos en el
servidor puede llevar no sólo a una degradación del rendimiento, sino también a
fallos más graves.
 Los sistemas gestores de bases de datos están optimizados para manejar
conjuntos, los cursores no, están concebidos para trabajar con cada elemento
de forma independiente.

Conclusiones
Hasta aquí se vieron los elementos básicos de dos contenidos muy importantes y de
amplia utilización en el trabajo con bases de datos: los triggers y los cursores.
El uso de los triggers y cursores pueden resultar muy útiles ante determinadas
necesidades de información o de comportamiento de una base de datos; pero un uso
desmedido de ambos trae consigo demora en la ejecución de las consultas y un gran
consumo de recurso por parte del servidor de base de datos.

También podría gustarte