Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Problema:
Una librería almacena los datos de sus libros en una tabla denominada "libros" y controla las
actualizaciones del precio de los libros almacenando en la tabla "control" el nombre del usuario, la
fecha, el precio anterior y el nuevo.
codigo number(6),
titulo varchar2(40),
autor varchar2(30),
editorial varchar2(20),
precio number(6,2)
);
usuario varchar2(30),
fecha date,
codigo number(6),
precioanterior number(6,2),
precionuevo number(6,2) );
on libros
begin
end tr_actualizar_precio_libros;
Cuando el trigger se dispare, antes de ingresar los valores a la tabla, almacenará en "control",
además del nombre del usuario y la fecha, el precio anterior del libro y el nuevo valor.
El trigger no se disparó, pues fue definido para actualizaciones del campo "precio" unicamente.
Verifiquémoslo:
on libros
begin
if (:new.precio>50) then
:new.precio:=floor(:new.precio);
end if;
end tr_actualizar_precio_libros;
on libros
begin
end tr_libros;
Ingresamos un registro:
Resultado:
USUARIO FECHA CODIGO PRECIOANTERIOR PRECIONUEVO
-----------------------------------------------------------------------------------
SYSTEM 20/03/08 21
La sentencia disparadora fue una inserción, por lo tanto, los campos ":old.codigo" y ":old.precio"
contienen "null", así que en "codigo" y en "precioanterior" se almacena "null"; el único campo con
valor diferente de "null" es "precionuevo" correspondiente al valor de ":new.precio".
Resultado:
USUARIO FECHA CODIGO PRECIOANTERIOR PRECIONUEVO
-----------------------------------------------------------------------------------
Analicemos: actualizamos el precio, por lo tanto, ninguno de los campos consultados contiene
"null".
Actualizamos un campo diferente de "precio" de un libro:
Resultado:
USUARIO FECHA CODIGO PRECIOANTERIOR PRECIONUEVO
-----------------------------------------------------------------------------------
Actualizamos el autor, por lo tanto, los campos ":old.precio" y ":new.precio" son iguales.
Resultado:
USUARIO FECHA CODIGO PRECIOANTERIOR PRECIONUEVO
-----------------------------------------------------------------------------------
Analicemos: la sentencia que disparó el trigger fue un "delete", por lo tanto, el campo
":new.precio" contiene "null".
Veamos qué informa el diccionario "user_triggers" respecto del trigger anteriormente creado:
Problema:
Una empresa almacena los datos de sus empleados en una tabla denominada "empleados". En
una tabla denominada "controlCambios" guarda los cambios que se realizan en la tabla
"empleados", en ella almacena el nombre del usuario que realiza la modificación, la fecha, el valor
anterior del campo modificado y el nuevo valor.
domicilio varchar2(30),
seccion varchar2(20)
);
usuario varchar2(30),
fecha date,
datoanterior varchar2(30),
datonuevo varchar2(30)
);
before update
on empleados
begin
if updating('documento') then
end if;
if updating('nombre') then
end if;
if updating('domicilio') then
end if;
if updating('seccion') then
end if;
end tr_actualizar_empleados;
before insert
on empleados
begin
end tr_ingresar_empleados;
Creamos un tercer trigger sobre "empleados" que se active cuando eliminamos un registro en
"empleados", debe almacenar en "controlCambios" el nombre del usuario que realiza la
eliminación, la fecha, el documento en "datoanterior" y "null" en "datonuevo":
before delete
on empleados
begin
end tr_eliminar_empleados;
Los tres triggers están habilitados. Consultamos el diccionario "user_triggers" para corroborarlo:
from user_triggers
from user_triggers
from user_triggers
from user_triggers
Consultamos el diccionario "user_triggers" para comprobar que el estado (status) de todos los
triggers establecidos sobre "empleados" es habilitado:
from user_triggers
Los tres trigger establecidos sobre "empleados" han sido habilitados. Se activarán ante cualquier
sentencia "insert", "update" y "delete".
Disparador (eliminar)
Problema:
Una librería almacena los datos de sus libros en una tabla denominada "libros" y controla las
acciones que los empleados realizan sobre dicha tabla almacenando en la tabla "control" el
nombre del usuario, la fecha, y el tipo de modificación que se realizó sobre la tabla "libros".
codigo number(6),
titulo varchar2(40),
autor varchar2(30),
editorial varchar2(20),
precio number(6,2)
);
usuario varchar2(30),
fecha date,
operacion varchar2(20)
);
Creamos un desencadenador que se active cuando ingresamos un nuevo registro en "libros", debe
almacenar en "control" el nombre del usuario que realiza el ingreso, la fecha e "insercion" en
"operacion":
create or replace trigger tr_ingresar_libros
before insert
on libros
begin
end tr_ingresar_libros;
Creamos un segundo disparador que se active cuando modificamos algún campo de "libros" y
almacene en "control" el nombre del usuario que realiza la actualización, la fecha y en "operacion"
coloque el nombre del campo actualizado:
before update
on libros
begin
if updating('codigo') then
end if;
if updating('titulo') then
end if;
if updating('autor') then
end if;
if updating('editorial') then
end if;
if updating('precio') then
insert into control values(user,sysdate,'precio');
end if;
end tr_actualizar_libros;
Creamos un tercer trigger sobre "libros" que se active cuando eliminamos un registro de "libros",
debe almacenar en "control" el nombre del usuario que realiza la eliminación, la fecha y "borrado"
en "operacion":
before delete
on libros
begin
end tr_eliminar_libros;
from user_triggers
Hay tres.
Hay 5 registros.
2 nuevos registros.
from user_triggers
where table_name = 'LIBROS';
Problema:
En el siguiente ejemplo se muestra la tabla del 3. La variable "f" comienza en cero (límite inferior
del for) y se va incrementando de a uno; el ciclo se repite hasta que "f" llega a 5 (límite superior
del for), cuando llega a 6, el bucle finaliza.
execute dbms_output.enable(20000);
begin
dbms_output.put_line('3x'||to_char(f)||'='||to_char(f*3));
end loop;
end;
Para que el contador "f" se decremente en cada repetición, colocamos "reverse"; el contador
comenzará por el valor del límite superior (5) y finalizará al llegar al límite inferior (0)
decrementando de a uno. En este ejemplo mostramos la tabla del 3 desde el 5 hasta el 0:
begin
dbms_output.put_line('3*'||to_char(f)||'='||to_char(f*3));
end loop;
end;
Se pueden colocar "for" dentro de otro "for". Por ejemplo, con las siguientes líneas imprimimos las
tablas del 2 y del 3 del 1 al 9:
begin
end;
execute dbms_output.enable(20000);
begin
dbms_output.put_line('3x'||to_char(f)||'='||to_char(f*3));
end loop;
end;
begin
dbms_output.put_line('3*'||to_char(f)||'='||to_char(f*3));
end loop;
end;
begin
dbms_output.put_line(to_char(f)||'x'||to_char(g)||'='||to_char(f*g));
/
Control de flujo (while loop)
Problema:
Luego, declaramos la variable numérica "numero" y le asignamos el valor cero; tal variable
contendrá el multiplicando. También declaramos la variable "resultado" de tipo numérico
que almacenará el resultado de cada multiplicación. Comenzamos el bloque "begin... end"
con la estructura repetitiva "while... loop". La condición chequea si el valor de la variable
"numero" es menmor o igual a 5; las sentencias que se repetirán serán:
- imprimir "resultado" y
- incrementar la variable "numero" para que la siguiente vez que se entre al bucle
repetitivo se multiplique 3 por otro número.
declare
numero number:=0;
resultado number;
begin
resultado:=3*numero;
dbms_output.put_line('3*'||to_char(numero)||'='||to_char(resultado));
numero:=numero+1;
end loop;
end;
declare
numero number:=0;
resultado number;
begin
resultado:=3*numero;
dbms_output.put_line('3*'||to_char(numero)||'='||to_char(resultado));
numero:=numero+1;
end loop;
end;