117 - Errores definidos por el usuario en trigger


Problema:

Una librería almacena en "libros" los datos de sus libros para la venta. En una tabla denominada "control" almacena el nombre del usuario y la fecha, cada vez que se actualiza la tabla "libros".

Eliminamos las tablas "libros" y "control":

 drop table libros;
 drop table control;

Creamos las tablas:

 create table libros(
  codigo number(5),
  titulo varchar2(40),
  autor varchar2(30),
  editorial varchar2(20),
  precio number(6,2)
 );

 create table control(
  usuario varchar2(30),
  fecha date
 );
 

Ingresamos algunos registros en "libros":

 insert into libros values (101,'Uno','Richard Bach','Planeta',25); 
 insert into libros values (102,'Matematica estas ahi','Paenza','Nuevo siglo',12); 
 insert into libros values (103,'El aleph','Borges','Emece',28);
 insert into libros values (104,'Aprenda PHP','Molina','Nuevo siglo',55); 
 insert into libros values (105,'El experto en laberintos','Gaskin','Planeta',23); 

Creamos un trigger de actualización a nivel de fila sobre la tabla "libros" que se dispare antes que se ejecute una actualización. Ante cualquier modificación de los registros de "libros", se debe ingresar en la tabla "control", el nombre del usuario que realizó la actualización y la fecha. Pero, controlamos que NO se permita modificar el campo "codigo", en caso de suceder, la acción no debe realizarse y debe mostrarse un mensaje de error indicándolo:

 create or replace trigger tr_actualizar_libros
 before update
 on libros
 for each row
 begin
   if updating('codigo') then
    raise_application_error(-20001,'No se puede modificar el código de los libros');
   else
    insert into control values(user,sysdate);
   end if;
 end;
 /

Aumentamos el precio de todos los libros de editorial "Planeta":

 update libros set precio=precio+precio*0.1  where editorial='Planeta';

Controlamos que los precios se han modificado y el trigger se ha disparado almacenando en "control" 2 registros:

 select *from libros;
 select *from control;

Intentamos modificar el código de un libro:

 update libros set codigo=109 where codigo=101;

Note que muestra el mensaje de error definido por nosotros. El trigger se disparó y se ejecutó "raise_application_error", por lo tanto, el código no se modificó. Controlamos que el código no se modificó:

 select *from libros;

Reemplazamos el trigger creado anteriormente para que ahora se dispare DESPUES (after) de cualquier modificación de los registros de "libros"; debe realizar lo mismo que el anterior, ingresar en la tabla "control", el nombre del usuario que realizó la actualización y la fecha. Pero, controlando que NO se permita modificar el campo "codigo", en caso de suceder, la acción no debe revertirse y debe mostrarse un mensaje de error indicándolo:

 create or replace trigger tr_actualizar_libros
 after update
 on libros
 for each row
 begin
   if updating('codigo') then
    raise_application_error(-20001,'No se puede modificar el código de los libros');
   else
    insert into control values(user,sysdate);
   end if;
 end;
 / 

Intentamos modificar el código de un libro:

 update libros set codigo=109 where codigo=101;

Note que muestra el mensaje de error definido por nosotros. El trigger fue definido "after", es decir, se disparó luego de ejecutarse la actualización, pero también se ejecutó "raise_application_error", por lo tanto, la sentencia "update" se deshizo.

Controlamos que el código no se modificó:

 select *from libros;

Ingresemos el siguiente lote de comandos en el Oracle SQL Developer:

 drop table libros;
 drop table control;

 create table libros(
  codigo number(5),
  titulo varchar2(40),
  autor varchar2(30),
  editorial varchar2(20),
  precio number(6,2)
 );

 create table control(
  usuario varchar2(30),
  fecha date
 );
 
 insert into libros values (101,'Uno','Richard Bach','Planeta',25); 
 insert into libros values (102,'Matematica estas ahi','Paenza','Nuevo siglo',12); 
 insert into libros values (103,'El aleph','Borges','Emece',28);
 insert into libros values (104,'Aprenda PHP','Molina','Nuevo siglo',55); 
 insert into libros values (105,'El experto en laberintos','Gaskin','Planeta',23); 

 create or replace trigger tr_actualizar_libros
 before update
 on libros
 for each row
 begin
   if updating('codigo') then
    raise_application_error(-20001,'No se puede modificar el código de los libros');
   else
    insert into control values(user,sysdate);
   end if;
 end;
 /
 
 -- Aumentamos el precio de todos los libros de editorial "Planeta":
 update libros set precio=precio+precio*0.1  where editorial='Planeta';
 -- Controlamos que los precios se han modificado y el trigger se ha disparado
 -- almacenando en "control" 2 registros:

 select *from libros;
 select *from control;

 -- Intentamos modificar el código de un libro:
 update libros set codigo=109 where codigo=101;
 -- Note que muestra el mensaje de error definido por nosotros.
 
 -- Controlamos que el código no se modificó:
 select *from libros;

 -- Reemplazamos el trigger creado anteriormente para que ahora se dispare DESPUES (after)
 -- de cualquier modificación de los registros de "libros";
 create or replace trigger tr_actualizar_libros
 after update
 on libros
 for each row
 begin
   if updating('codigo') then
    raise_application_error(-20001,'No se puede modificar el código de los libros');
   else
    insert into control values(user,sysdate);
   end if;
 end;
 /
 
 -- Intentamos modificar el código de un libro:
 update libros set codigo=109 where codigo=101;

 -- Controlamos que el código no se modificó:
 select *from libros;

La ejecución de este lote de comandos SQL genera una salida similar a:

SQL Developer errores definidos por el usuario


Retornar