Bases de Datos



                  Unidad


             El Lenguaje PL/SQL
                  (Triggers)




            2011  Erwin Fischer   2
Disparadores (Triggers)
• Un triggers define una acción que la BD debe realizar
  cuando tenga lugar un determinado suceso en la
  aplicación
• Un trigger, al igual que una función o procedimiento es
  un objeto de la base de datos.
• En la práctica es un procedimiento almacenado, pero de
  uso interno al DBMS, por lo cual no usa parámetros.
• Se asocian a tablas y operaciones de modificación
  básicas sobre ellas (Insert, Delete, Update).
• Se ejecuta automáticamente cuando alguna de estas
  operaciones básicas sucede, antes que la modificación
  se haga permanente en la base de datos.
• Puede incorporar cualquier tipo o agrupación de
  sentencias SQL, al igual que un procedimiento
  almacenado.



                        2011  Erwin Fischer                3
Disparadores (Triggers)
• Los triggers pueden utilizarse para imponer ciertas restricciones
  de integridad referencial, para imponer reglas de negocios
  complejas, o para auditar los cambios en los datos
• Los triggers se basan en el modelo ECA (Event-Condition-Action,
  evento-condición-acción)
• El Evento que dispara la regla especificada, en Oracle puede ser:
     • Una instrucción INSERT, UPDATE, DELETE
     • Una instrucción CREATE, ALTER o DROP
     • Un arranque de la BD o detención de la instancia
     • Un inicio o fin de sesión por parte del usuario
     • Un mensaje de Error
• La Condición que determina si la acción que debe
  ejecutarse. Es opcional, pero si se especifica, la acción
  se ejecutará si la condición se evalúa como verdadera
• La Acción que hay que llevar a cabo. Este bloque
  contiene el código y las instrucciones SQL que se
  ejecutan cuando se produce el evento y la condición es
  verdadera
                          2011  Erwin Fischer                        4
ECA-Rules (Event-Condition-Action rules)

• Una vez que un set de reglas ha sido definidas el
  ADBMS monitorea los eventos relevantes. Un evento
  relevante es aquel que tiene definida alguna regla.

• Cada vez que el ADBMS detecta la ocurrencia de un
  evento relevante, notifica al componente encargado de
  la ejecución de la regla asociada. Esta notificación se
  denomina “event signalling” o señalización de eventos.

• En consecuencia, todas las reglas definidas para
  responder a dicho evento se “disparan” (trigger), y
  deben ser ejecutadas.

• La ejecución de reglas incorpora la evaluación de
  condiciones, y si dichas condiciones satisfacen, se
  ejecuta la acción.


                         2011  Erwin Fischer               5
Disparadores (Triggers)
Aquí se presenta la sintaxis para crear un disparador en Oracle (que se
diferencia levemente de la sintaxis estándar de SQL):

CREATE [OR REPLACE] TRIGGER <trigger_name>
 {BEFORE|AFTER} {INSERT|DELETE|UPDATE} ON <table_name>
 [REFERENCING [NEW AS <new_row_name>] [OLD AS <old_row_name>]]
 [FOR EACH ROW [WHEN (<trigger_condition>)]]
<trigger_body>

Se puede usar solamente TRIGGERS BEFORE o AFTER para tablas INSTEAD
OF triggers son utilizados para vistas (típicamente para vistas de
actualización)

Se puede especificar hasta tres disparadores de eventos usando la palabra
clave OR.
... INSERT ON R ...
... INSERT OR DELETE OR UPDATE ON R ...
... UPDATE OF A, B OR INSERT ON R ...
                           2011  Erwin Fischer                             6
Disparadores (Triggers)
Se muestra la sintaxis de Oracle para crear triggers a través de un
  ejemplo basado en las dos tablas siguientes:

CREATE TABLE T4 (a INTEGER, b CHAR(10));
CREATE TABLE T5 (c CHAR(10), d INTEGER);

CREATE TRIGGER trig1
AFTER INSERT ON T4
REFERENCING NEW AS newRow
FOR EACH ROW
WHEN (newRow.a <= 10)
 BEGIN
  INSERT INTO T5 VALUES(:newRow.b, :newRow.a);
 END trig1;




                          2011  Erwin Fischer                        7
Disparadores (Triggers)
CREATE TRIGGER TopeDeManejoPropiedadEmpleado
BEFORE INSERT OR UPDATE ON Propiedad
FOR EACH ROW
DECLARE
 vcontP NUMBER;
BEGIN
  SELECT COUNT(*) INTO vcontP
  FROM Propiedad
  WHERE numEmpleado = new.numEmpleado;
  IF vcontP = 100
        Raise_application_error(-2000, („Empleado „||
        new.numEmpleado|| „ ya administra 100 propiedades‟);
  END IF
END




                       2011  Erwin Fischer                    8
Disparadores (Triggers)
create table Person (age int);

CREATE TRIGGER PersonCheckAge
  AFTER INSERT OR UPDATE OF age ON Person
  FOR EACH ROW
  BEGIN
     IF (:new.age < 0) THEN
      RAISE_APPLICATION_ERROR(-20000, 'no negative age
  allowed');
     END IF;
  END;
  .
  RUN;

Si intentamos ejecutar la inserción:

insert into Person values (-3);
                          2011  Erwin Fischer           9
Create Sequence

 • Es un objeto de base de datos
 • Se utiliza para crear
   una secuencia, para
   generar enteros únicos.
 • Por ejemplo se puede
   utilizar secuencias para generar
   automáticamente valores de clave
   principal.


              2011  Erwin Fischer    10
Create Sequence un ejemplo

 CREATE SEQUENCE seqCliente
 START WITH 1000
 INCREMENT BY 1
 NOCACHE
 NOCYCLE;

 La primera referencia a seqCliente.nextval retorna 1000. la
 segunda retorna 1001.
 Cada consulta posterior devolverá un valor mayor en 1 que
 la referencia anterior.


                       2011  Erwin Fischer                    11
Un Trigger con Sequence

 • Supongamos que tenemos la
   siguiente tabla cliente
   Create table Cliente(
   idCliente number,
   Nombre     varchar2(30)
   )
 • utilizando la secuencia
   seqCliente, podemos crear el
   siguiente trigger.

              2011  Erwin Fischer   12
El trigger


Create or Replace trigger trClienteId
Before insert on Cliente
for each row
begin
 Select seqCliente.nextval into :new.idCliente
 from dual;
end;




                 2011  Erwin Fischer            13
Insertando registros



 • Luego para insertar un registro en
   la tabla cliente, bastaría hacer el
   siguiente insert:
   insert into Cliente (nombre)
   Values (‘Juan Perez’)

   – Observe que no hemos insertado el
     atributo idCliente

               2011  Erwin Fischer      14
Consultando Cliente



 • Si consultamos la tabla cliente
   Select * from Cliente




   Vemos que se ha insertado el Idcliente 1000

                    2011  Erwin Fischer         15
Predicados
 • Dentro de un trigger se pueden utilizar
   predicados, que retornan valores booleanos,
   para identificar la acción que esta realizando
 • Inserting: Devuelve verdadero si la
   instrucción que disparó el trigger fue un
   «Insert»
 • Updating: Devuelve verdadero si la
   instrucción que disparó el trigger fue un
   «Update»
 • Deleting: Devuelve verdadero si la
   instrucción que disparó el trigger fue un
   «Delete»

                   2011  Erwin Fischer             16
Trigger con predicado

 Create or Replace trigger trClienteId
 Before insert on Cliente
 for each row
 begin
  if inserting then
   Select seqCliente.nextval into :new.idCliente
  from dual;
  else
   :new.idCliente = 0;
  end if;
 End trClienteId;

                     2011  Erwin Fischer          17
• Ahora tomar en cuenta que el
  siguiente insert obtiene el mismo
  resultado del trigger, pero sin
  activar el trigger.
• Desactivando el trigger
 Alter trigger trClienteId disable;


  insert into Cliente
  Values (seqCliente.nextval, ‘Juan
   Perez’)
              2011  Erwin Fischer    18
Consultando cliente
nuevamente
INSERT   into Cliente Values (seqCliente.nextval, ‘Juan Perez’)



   • Select * from Cliente




                         2011  Erwin Fischer                     19
Disparadores (Triggers)
Exhibiendo errores de la definición del disparador

Como para los procedimientos PL/SQL si obtiene un mensaje de
  error en la creación del triggers, puede ver el error con:

show errors trigger <trigger_name>;

Alternativamente se puede usar,

SHO ERR (short for SHOW ERRORS)


Notar que los números de líneas reportados no son exactos.




                         2011  Erwin Fischer                  20
Disparadores (Triggers)

Para ver una lista de los triggers definidos usar:

select trigger_name
from user_triggers;

Para mas detalles de un trigger en particular:

select trigger_type, triggering_event, table_name,
  referencing_names, trigger_body
from user_triggers
where trigger_name = '<trigger_name>';



                   2011  Erwin Fischer              21
Eliminación y desactivación de Triggers
• Para eliminar un trigger se utiliza:
   Drop trigger «nombre_trigger»;
• Para desactivar un trigger se utiliza
   Alter trigger «nombre_trigger» disable;
• Para activar un trigger se utiliza
   Alter trigger «nombre_trigger» enable;
• Para activar todos los trigger de una tabla se
  utiliza
   Alter table «nombre_tabla» enable all
     triggers;


                     2011  Erwin Fischer          22
Triggers

                                                     Autor
Ejercicio (eliminación en cascada)                IdAutor


Cree un trigger que cada vez que se elimine
un autor, elimine todos los registros de
libros asociados a ese autor
                                                     Libro
                                                  IdLibro
                                                  IdAutor




                           2011  Erwin Fischer              23
Triggers
                                                                         Compra

Ejercicio 1
                                                                      IdCompra
                                                                      Fecha


•   Para un sistema de Administración de
    stock en Bodega, se requiere
    implementar la siguiente funcionalidad                             DetalleCompra
                                                        Producto
    activa a través de Triggers:                     IdProducto       IdCompra
                                                     NombreProducto   IdProducto
                                                     StockActual      Cantidad
    Cada vez que se agregue un registro de
    detalle de compra, se deberá actualizar
    en forma automática la existencia en
    Stock actual.

Evento: DetalleCompra.Insert
Condición: -
Acción: Producto.Update(StockActual)




                              2011  Erwin Fischer                                     24
Triggers
                                                                         Compra
                                                                      IdCompra
Ejercicio 2                                                           Fecha



•    Ampliar el Sistema, agregando registro
     de mermas (pérdidas)
                                                                      DetalleCompra
                                                        Producto
                                                     IdProducto       IdCompra
     Cada vez que se registre una merma,             NombreProducto
                                                                      IdProducto
                                                                      Cantidad
     se deberá actualizar en forma
                                                     StockActual

     automática la existencia en Stock
     actual.
                                                         Merma
                                                     IdMerma
Evento: Merma.Insert                                 Fecha
Condición: -                                         IdProducto
                                                     Cantidad
Acción: Producto.Update(StockActual)




                              2011  Erwin Fischer                                    25
Triggers
                                                                          Cliente
                                                                       IdCliente
Ejercicio 3

•   Autómata de Giro Bancario

    Cada vez que un cliente quiere hacer un             LineaCredito      Cuenta
                                                                       IdCuenta
    giro, el sistema deberá verificar que su           IdLinea
                                                                       IdCliente
                                                       IdCuenta
    saldo de cuenta corriente o en su defecto su       Saldo           Saldo
    cupo de línea de crédito sea suficiente para
    cubrir la operación.
    Si la suma del saldo disponible en la cuenta
    y el saldo de la línea no logra cubrir, se            UsoLinea           Giro
                                                                        IdGiro
    deberá anular la transacción, en caso               IdUso
                                                                        IdCuenta
                                                        IdLinea
    contrario, se deberá registrar el nuevo saldo       Fecha           Fecha
    y/o nuevo cupo de línea de crédito y detalle        Monto           Monto

    de la utilización de la línea.

Solución:   TAREA, grupal y publicar en su blog


                                2011  Erwin Fischer                                26
Investigar o Identificar Triggers

• Con su grupo de trabajo, identifique las situaciones en
  que seria deseable algún tipo de funcionalidad activa o
  autonomía.

• Para cada uno de ellos defina el evento, condición y
  acción.

• Publique en su blog, las situaciones y el o los triggers
  asociados que resuelven dicha situación.




                          2011  Erwin Fischer               27
Unidad - PL/SQL - Triggers



 • Si tiene una sugerencia, comentario
   u observación para mejorar este
   material, agradecería me envíe un
   mail a erfisch@gmail.com.

 Atentamente
 Profesor Erwin Fischer

               2011  Erwin Fischer      28

Triggers

  • 1.
    Bases de Datos Unidad El Lenguaje PL/SQL (Triggers) 2011  Erwin Fischer 2
  • 2.
    Disparadores (Triggers) • Untriggers define una acción que la BD debe realizar cuando tenga lugar un determinado suceso en la aplicación • Un trigger, al igual que una función o procedimiento es un objeto de la base de datos. • En la práctica es un procedimiento almacenado, pero de uso interno al DBMS, por lo cual no usa parámetros. • Se asocian a tablas y operaciones de modificación básicas sobre ellas (Insert, Delete, Update). • Se ejecuta automáticamente cuando alguna de estas operaciones básicas sucede, antes que la modificación se haga permanente en la base de datos. • Puede incorporar cualquier tipo o agrupación de sentencias SQL, al igual que un procedimiento almacenado. 2011  Erwin Fischer 3
  • 3.
    Disparadores (Triggers) • Lostriggers pueden utilizarse para imponer ciertas restricciones de integridad referencial, para imponer reglas de negocios complejas, o para auditar los cambios en los datos • Los triggers se basan en el modelo ECA (Event-Condition-Action, evento-condición-acción) • El Evento que dispara la regla especificada, en Oracle puede ser: • Una instrucción INSERT, UPDATE, DELETE • Una instrucción CREATE, ALTER o DROP • Un arranque de la BD o detención de la instancia • Un inicio o fin de sesión por parte del usuario • Un mensaje de Error • La Condición que determina si la acción que debe ejecutarse. Es opcional, pero si se especifica, la acción se ejecutará si la condición se evalúa como verdadera • La Acción que hay que llevar a cabo. Este bloque contiene el código y las instrucciones SQL que se ejecutan cuando se produce el evento y la condición es verdadera 2011  Erwin Fischer 4
  • 4.
    ECA-Rules (Event-Condition-Action rules) •Una vez que un set de reglas ha sido definidas el ADBMS monitorea los eventos relevantes. Un evento relevante es aquel que tiene definida alguna regla. • Cada vez que el ADBMS detecta la ocurrencia de un evento relevante, notifica al componente encargado de la ejecución de la regla asociada. Esta notificación se denomina “event signalling” o señalización de eventos. • En consecuencia, todas las reglas definidas para responder a dicho evento se “disparan” (trigger), y deben ser ejecutadas. • La ejecución de reglas incorpora la evaluación de condiciones, y si dichas condiciones satisfacen, se ejecuta la acción. 2011  Erwin Fischer 5
  • 5.
    Disparadores (Triggers) Aquí sepresenta la sintaxis para crear un disparador en Oracle (que se diferencia levemente de la sintaxis estándar de SQL): CREATE [OR REPLACE] TRIGGER <trigger_name> {BEFORE|AFTER} {INSERT|DELETE|UPDATE} ON <table_name> [REFERENCING [NEW AS <new_row_name>] [OLD AS <old_row_name>]] [FOR EACH ROW [WHEN (<trigger_condition>)]] <trigger_body> Se puede usar solamente TRIGGERS BEFORE o AFTER para tablas INSTEAD OF triggers son utilizados para vistas (típicamente para vistas de actualización) Se puede especificar hasta tres disparadores de eventos usando la palabra clave OR. ... INSERT ON R ... ... INSERT OR DELETE OR UPDATE ON R ... ... UPDATE OF A, B OR INSERT ON R ... 2011  Erwin Fischer 6
  • 6.
    Disparadores (Triggers) Se muestrala sintaxis de Oracle para crear triggers a través de un ejemplo basado en las dos tablas siguientes: CREATE TABLE T4 (a INTEGER, b CHAR(10)); CREATE TABLE T5 (c CHAR(10), d INTEGER); CREATE TRIGGER trig1 AFTER INSERT ON T4 REFERENCING NEW AS newRow FOR EACH ROW WHEN (newRow.a <= 10) BEGIN INSERT INTO T5 VALUES(:newRow.b, :newRow.a); END trig1; 2011  Erwin Fischer 7
  • 7.
    Disparadores (Triggers) CREATE TRIGGERTopeDeManejoPropiedadEmpleado BEFORE INSERT OR UPDATE ON Propiedad FOR EACH ROW DECLARE vcontP NUMBER; BEGIN SELECT COUNT(*) INTO vcontP FROM Propiedad WHERE numEmpleado = new.numEmpleado; IF vcontP = 100 Raise_application_error(-2000, („Empleado „|| new.numEmpleado|| „ ya administra 100 propiedades‟); END IF END 2011  Erwin Fischer 8
  • 8.
    Disparadores (Triggers) create tablePerson (age int); CREATE TRIGGER PersonCheckAge AFTER INSERT OR UPDATE OF age ON Person FOR EACH ROW BEGIN IF (:new.age < 0) THEN RAISE_APPLICATION_ERROR(-20000, 'no negative age allowed'); END IF; END; . RUN; Si intentamos ejecutar la inserción: insert into Person values (-3); 2011  Erwin Fischer 9
  • 9.
    Create Sequence •Es un objeto de base de datos • Se utiliza para crear una secuencia, para generar enteros únicos. • Por ejemplo se puede utilizar secuencias para generar automáticamente valores de clave principal. 2011  Erwin Fischer 10
  • 10.
    Create Sequence unejemplo CREATE SEQUENCE seqCliente START WITH 1000 INCREMENT BY 1 NOCACHE NOCYCLE; La primera referencia a seqCliente.nextval retorna 1000. la segunda retorna 1001. Cada consulta posterior devolverá un valor mayor en 1 que la referencia anterior. 2011  Erwin Fischer 11
  • 11.
    Un Trigger conSequence • Supongamos que tenemos la siguiente tabla cliente Create table Cliente( idCliente number, Nombre varchar2(30) ) • utilizando la secuencia seqCliente, podemos crear el siguiente trigger. 2011  Erwin Fischer 12
  • 12.
    El trigger Create orReplace trigger trClienteId Before insert on Cliente for each row begin Select seqCliente.nextval into :new.idCliente from dual; end; 2011  Erwin Fischer 13
  • 13.
    Insertando registros •Luego para insertar un registro en la tabla cliente, bastaría hacer el siguiente insert: insert into Cliente (nombre) Values (‘Juan Perez’) – Observe que no hemos insertado el atributo idCliente 2011  Erwin Fischer 14
  • 14.
    Consultando Cliente •Si consultamos la tabla cliente Select * from Cliente Vemos que se ha insertado el Idcliente 1000 2011  Erwin Fischer 15
  • 15.
    Predicados • Dentrode un trigger se pueden utilizar predicados, que retornan valores booleanos, para identificar la acción que esta realizando • Inserting: Devuelve verdadero si la instrucción que disparó el trigger fue un «Insert» • Updating: Devuelve verdadero si la instrucción que disparó el trigger fue un «Update» • Deleting: Devuelve verdadero si la instrucción que disparó el trigger fue un «Delete» 2011  Erwin Fischer 16
  • 16.
    Trigger con predicado Create or Replace trigger trClienteId Before insert on Cliente for each row begin if inserting then Select seqCliente.nextval into :new.idCliente from dual; else :new.idCliente = 0; end if; End trClienteId; 2011  Erwin Fischer 17
  • 17.
    • Ahora tomaren cuenta que el siguiente insert obtiene el mismo resultado del trigger, pero sin activar el trigger. • Desactivando el trigger Alter trigger trClienteId disable; insert into Cliente Values (seqCliente.nextval, ‘Juan Perez’) 2011  Erwin Fischer 18
  • 18.
    Consultando cliente nuevamente INSERT into Cliente Values (seqCliente.nextval, ‘Juan Perez’) • Select * from Cliente 2011  Erwin Fischer 19
  • 19.
    Disparadores (Triggers) Exhibiendo erroresde la definición del disparador Como para los procedimientos PL/SQL si obtiene un mensaje de error en la creación del triggers, puede ver el error con: show errors trigger <trigger_name>; Alternativamente se puede usar, SHO ERR (short for SHOW ERRORS) Notar que los números de líneas reportados no son exactos. 2011  Erwin Fischer 20
  • 20.
    Disparadores (Triggers) Para veruna lista de los triggers definidos usar: select trigger_name from user_triggers; Para mas detalles de un trigger en particular: select trigger_type, triggering_event, table_name, referencing_names, trigger_body from user_triggers where trigger_name = '<trigger_name>'; 2011  Erwin Fischer 21
  • 21.
    Eliminación y desactivaciónde Triggers • Para eliminar un trigger se utiliza: Drop trigger «nombre_trigger»; • Para desactivar un trigger se utiliza Alter trigger «nombre_trigger» disable; • Para activar un trigger se utiliza Alter trigger «nombre_trigger» enable; • Para activar todos los trigger de una tabla se utiliza Alter table «nombre_tabla» enable all triggers; 2011  Erwin Fischer 22
  • 22.
    Triggers Autor Ejercicio (eliminación en cascada) IdAutor Cree un trigger que cada vez que se elimine un autor, elimine todos los registros de libros asociados a ese autor Libro IdLibro IdAutor 2011  Erwin Fischer 23
  • 23.
    Triggers Compra Ejercicio 1 IdCompra Fecha • Para un sistema de Administración de stock en Bodega, se requiere implementar la siguiente funcionalidad DetalleCompra Producto activa a través de Triggers: IdProducto IdCompra NombreProducto IdProducto StockActual Cantidad Cada vez que se agregue un registro de detalle de compra, se deberá actualizar en forma automática la existencia en Stock actual. Evento: DetalleCompra.Insert Condición: - Acción: Producto.Update(StockActual) 2011  Erwin Fischer 24
  • 24.
    Triggers Compra IdCompra Ejercicio 2 Fecha • Ampliar el Sistema, agregando registro de mermas (pérdidas) DetalleCompra Producto IdProducto IdCompra Cada vez que se registre una merma, NombreProducto IdProducto Cantidad se deberá actualizar en forma StockActual automática la existencia en Stock actual. Merma IdMerma Evento: Merma.Insert Fecha Condición: - IdProducto Cantidad Acción: Producto.Update(StockActual) 2011  Erwin Fischer 25
  • 25.
    Triggers Cliente IdCliente Ejercicio 3 • Autómata de Giro Bancario Cada vez que un cliente quiere hacer un LineaCredito Cuenta IdCuenta giro, el sistema deberá verificar que su IdLinea IdCliente IdCuenta saldo de cuenta corriente o en su defecto su Saldo Saldo cupo de línea de crédito sea suficiente para cubrir la operación. Si la suma del saldo disponible en la cuenta y el saldo de la línea no logra cubrir, se UsoLinea Giro IdGiro deberá anular la transacción, en caso IdUso IdCuenta IdLinea contrario, se deberá registrar el nuevo saldo Fecha Fecha y/o nuevo cupo de línea de crédito y detalle Monto Monto de la utilización de la línea. Solución: TAREA, grupal y publicar en su blog 2011  Erwin Fischer 26
  • 26.
    Investigar o IdentificarTriggers • Con su grupo de trabajo, identifique las situaciones en que seria deseable algún tipo de funcionalidad activa o autonomía. • Para cada uno de ellos defina el evento, condición y acción. • Publique en su blog, las situaciones y el o los triggers asociados que resuelven dicha situación. 2011  Erwin Fischer 27
  • 27.
    Unidad - PL/SQL- Triggers • Si tiene una sugerencia, comentario u observación para mejorar este material, agradecería me envíe un mail a erfisch@gmail.com. Atentamente Profesor Erwin Fischer 2011  Erwin Fischer 28