Procedimientos almacenados - Departamento de Ingeniería de

Anuncio
PROCEDIMIENTOS ALMACENADOS
Y TRIGGERS
Bases de Datos
Ingeniería de Sistemas y Computación
Universidad Nacional de Colombia
2007
Procedimientos almacenados
Un procedimiento almacenado es un conjunto de sentencias SQL y
de control de flujo
Un procedimiento almacenado es una colección de
instrucciones guardadas en la Base de Datos
La ventaja de un procedimiento almacenado es que al ser
ejecutado, éste se ejecuta directamente en el motor de
bases de datos, el cual usualmente corre en un servidor
separado.
Bases de Datos - 2007
Procedimientos almacenados
Beneficios de los procedimientos almacenados:
Simplifican la ejecución de tareas repetitivas
Corren más rápido que las mismas instrucciones ejecutadas en
forma interactiva
Reducen el tráfico a través de la red
Pueden capturar errores antes que ellos puedan entrar a la
base de datos
Establece consistencia porque ejecuta las tareas de la misma
forma
Permite el desarrollo modular de aplicaciones
Ayuda a proveer seguridad
Puede forzar reglas y defaults complejos de los negocios
Bases de Datos - 2007
Tipos de procedimientos almacenados
Procedimientos almacenados definidos por el usuario
Son procedimientos definidos por el usuario que se
deben llamar explícitamente
Triggers
Son procedimientos definidos por el usuario que se
ejecutan automáticamente cuando se modifica un dato
en una tabla
Procedimientos del sistema
Procedimientos suministrados por el sistema
Procedimientos extendidos
Procedimientos que hacen llamadas al sistema
operativo y ejecutan tareas a ese nivel
Bases de Datos - 2007
Interactive Execution
Bases de Datos - 2007
Creación de un procedimiento almacenado
Bases de Datos - 2007
Ejecución de un procedimiento almacenado
Bases de Datos - 2007
Ventajas en el rendimiento
Un procedimiento almacenado se ejecuta más rápido que un
batch porque:
El procedimiento almacenado ya ha sido analizado
Ya se han resuelto las referencias a los objetos
referenciados en el procedimiento almacenado
No se necesita construir el árbol de búsqueda, él usa el
que se hace en el momento de compilarlo
No se necesita crear un plan de búsqueda, porque ya el
procedimiento tiene uno
Bases de Datos - 2007
Crear y borrar procedimientos almacenados
Sintaxis simplificada para create:
create proc procedure_name
as
statements
return
Ejemplo:
create proc proc_update_titles
as
update titles
set price = price * $0.95
where total_sales < 3000
return
Sintaxis simplificada para drop:
drop proc procedure_name
Ejemplo:
drop proc proc_update_titles
Bases de Datos - 2007
Crear procedimientos almacenados
Sintaxis para Sybase:
create procedure [owner.]procedure_name
[;number] [[ (]@parameter_name datatype
[= default] [output]
[, @parameter_name datatype
[= default] [output]]
...[)]]
[with recompile]
as sql_statements
Bases de Datos - 2007
Crear procedimientos almacenados
Sintaxis para SQL Server:
create procedure procedure_name
(parameter_name datatype default_value
[, parameter_name datatype default_value...] )
as
statements
return
Bases de Datos - 2007
Crear procedimientos almacenados
Sintaxis para Oracle:
CREATE [OR REPLACE]
PROCEDURE <procedure_name>
[(<param1> [IN|OUT|IN OUT] <type>,
<param2> [IN|OUT|IN OUT] <type>, ...)]
IS
-- Declaracion de variables locales
BEGIN
-- Sentencias
[EXCEPTION]
-- Sentencias control de excepcion
END [<procedure_name>];
Bases de Datos - 2007
Ejecutar procedimientos almacenados
Sintaxis simplificada:
[exec | execute] procedure_name
Ejemplo:
execute proc_update_titles
Bases de Datos - 2007
Variables
Los procedimientos almacenados pueden crear y usar
variables locales
Las variables sólo existen mientras exista el procedimiento
Las variables no las puede usar otro proceso
Bases de Datos - 2007
Sentencias válidas e inválidas
Un procedimiento almacenado puede:
Seleccionar y modificar datos
Crear tablas temporales y permanentes
Llamar otros procedimientos almacenados
Referenciar objetos de bases de datos
Un procedimiento almacenado no puede ejecutar:
use database
create view
create default
create rule
create procedure
create trigger
Bases de Datos - 2007
Procedimientos almacenados y permisos
Para permitir que otros usen un procedimiento almacenado, el
propietario debe dar los respectivos permisos
Sintaxis simplificada:
grant execute
on procedure_name
to user_list
Ejemplo:
grant execute
on proc_update_titles
to icastaneda, grupo5, aortizs
Bases de Datos - 2007
Crear procedimientos almacenados
Crear un procedimiento almacenado sencillo:
create proc proc_hello
as
print "Hello, <your_name>"
return
Ver el código fuente de un procedimiento:
sp_helptext proc_hello
Ejecutar el procedimiento:
exec proc_hello
Borrar los objetos de bases de datos:
drop proc proc_hello
Bases de Datos - 2007
Parámetros de entrada
An input Parámetro is a variable local to a
procedimiento almacenado that can receive a
value from the exec procedure Sentencia
Bases de Datos - 2007
Definir parámetros de entrada
Sintaxis simplificada:
create procedure procedure_name
(parameter_name datatype default_value
[, parameter_name datatype default_value...] )
as
statements
return
Bases de Datos - 2007
Pasar parámetros
Dos métodos para pasar valores a parámetros:
Paso de parámetros por posición
Paso de parámetros por nombre
Bases de Datos - 2007
Paso de parámetros por posición
Sintaxis para paso por posición:
[exec | execute] procedure_name value [, value...]
Ejemplo:
exec proc_author_info "Ringer“,"Albert"
au_lname
-------Ringer
Ringer
au_fname
-------Albert
Albert
title
----Is Anger the Enemy?
Life Without Fear
Los parámetros se deben pasar en el mismo orden en que
ellos aparecen en la sentencia create procedure
Como este método es más propenso a errores, se
aconseja el paso por nombre
Bases de Datos - 2007
Paso de parámetros por nombre
Sintaxis para paso por nombre:
[exec | execute] procedure procedure_name
parameter_name = value [, parameter_name = value ]
Ejemplo:
exec proc_author_info
@lname = "Ringer", @fname = "Albert"
au_lname
-------Ringer
Ringer
au_fname
-------Albert
Albert
title
----Is Anger the Enemy?
Life Without Fear
Los nombres de los parámetros en la sentencia exec deben
concordar con los nombres de los parámetros usados en la
sentencia create procedure
Los parámetros pueden pasar en cualquier orden
Bases de Datos - 2007
Valores por default
Se puede asignar un valor por default a un parámetro
cuando él no se indica en la sentencia exec
Ejemplo:
create proc proc_state_authors
(@state char(2) = "CA")
as
select au_lname, au_fname, state
from authors
where state = @state
return
exec proc_state_authors
-- No state value passed
au_lname
-------White
Green
...
state
----CA
CA
au_fname
-------Johnson
Marjorie
Bases de Datos - 2007
Parámetros de entrada: errores comunes
Los valores que se pasan no tienen el mismo tipo de datos que los
parámetros definidos
En la misma sentencia, se pasa un parámetro por posición después
de haber pasado un parámetro por nombre
Aunque no es recomendado, es posible mezclar los dos métodos
para pasar valores, sin embargo, después de pasar un valor a un
parámetro por nombre, todos los restantes de deben pasar por
nombre
Olvido de uno o más parámetros
El olvido de uno o más valores para los parámetros, hace que se
usen los valores por default
Los valores para los parámetros se pasan en un orden errado
Bases de Datos - 2007
Parámetros de entrada
Crear un procedimiento almacenado que tenga un parámetro de
entrada:
create proc proc_hello_param (@name varchar(30))
as
print "Hello %1!", @name
return
Ejecutar el procedimiento con y sin un valor para el parámetro de
entrada. Una sentencia fallará:
exec proc_hello_param
exec proc_hello_param "<yourname>"
Crear un procedimiento almacenado que tiene un valor por default para
un parámetro de entrada:
create proc proc_hello_def
(@name varchar(30) = "whoever you are")
as
print "Hello %1!", @name
return
Bases de Datos - 2007
Parámetros de entrada
• Ejecutar el procedimiento con y sin un valor para el
parámetro de entrada:
exec proc_hello_def
exec proc_hello_def "<yourname>"
• ¿Cuál procedimiento almacenado parece ser más
amigable?
• Borrar los objetos de bases de datos creados:
drop proc proc_hello_param, proc_hello_def
Bases de Datos - 2007
Retorno de valores
A return Parámetro is a variable local to a
procedimiento almacenado that can send a value
to the exec procedure Sentencia
Bases de Datos - 2007
Crear parámetros que retornan valores
Sintaxis simplificada:
create procedure procedure_name
(parameter_name datatype output
[, parameter_name datatype output...] )
as
statements
return
Bases de Datos - 2007
Usar parámetros que retornan valores
Sintaxis simplificada:
[exec | execute] procedure_name variable output
Los valores que retornan los parámetros se pasan automáticamente
al conjunto respuesta
El retorno de valores se pueden pasar por nombre o por posición
Se recomienda el paso por nombre
Bases de Datos - 2007
Legibilidad
Para hacer un código más legible:
Utilizar comentarios
Utilizar indentación
Usar espacios en blanco y dejar el código organizado en columnas
Declarar e iniciar las variables en un bloque
Establecer un conjunto de buenas prácticas para legibilidad
Bases de Datos - 2007
Chequeo de valores que van a ser parámetros de entrada
El servidor sólo chequea que los valores y sus respectivos
parámetros concuerden en el tipo de datos
Los procedimientos almacenados deben verificar que los valores
pasados se encuentren dentro del dominio establecido
Bases de Datos - 2007
Mensajes de error por omisión de valores para los
parámetros
Si un procedimiento almacenado requiere valores para los parámetros,
el usuario debe incluir un tratamiento de esos errores y un manejo de
mensajes de error
Ejemplo:
create proc proc_cutoff
(@title_id
char(6)
= NULL,
@max_price money
= NULL)
as
if @title_id is NULL or @max_price is NULL
begin
raiserror 20001
"Execution for this procedure is:
exec proc_cutoff title_id, max_price"
return
end
...
return
Bases de Datos - 2007
Retorno de valores de estado
A return status is a value that indicates whether or
not the procedure successfully completed
Bases de Datos - 2007
Retorno de valores de estado
Values
Meaning
Greater than 0
No predefined meaning; available
for user-detected errors
0
Successful completetion
-1 through –99
System-detected error
Less than –99
No predefined meaning; available
for user-detected erros
Bases de Datos - 2007
Retorno de valores de estado
Sintaxis simplificada:
create proc procedure_name
as
statements
return [return_status]
Ejemplo:
create proc proc_datacheck
as
if (select max(total_sales) from titles) < 3000
begin
print "All the books have sold
less than 3000."
return 100
end
else
...
return 0
Bases de Datos - 2007
Captura del valor del estado de retorno
Los valores de retorno se deben capturar en variables
Sintaxis simplificada:
[exec | execute] variable = procedure_name
parameter_list
Ejemplo:
declare @status int
exec @status = proc_datacheck
if @status = 100
exec proc_max_under_3000
else
print "proc_datacheck was successful"
Bases de Datos - 2007
Límite de anidamiento para procedimientos
Los procedimientos almacenados pueden llamar otros
procedimientos almacenados
El máximo nivel de anidamiento es 16
La variable @@nestlevel contiene el nivel de anidamiento
actual
Si se excede el nivel máximo:
Se abortan los procedimientos pendientes
El servidor retorna un error
Bases de Datos - 2007
Crear procedimientos con recompile
En un procedimiento, usar la opción with recompile
para forzar al servidor a crear un nuevo plan de
búsqueda cada vez que se ejecute el procedimiento
Sintaxis simplificada:
create proc procedure_name
with recompile
as
statements
return
Bases de Datos - 2007
Ejecución de procedimientos with recompile
Cuando se ejecute un procedimiento almacenado,
usar la opción with recompile para forzar al servidor
a crear un nuevo plan de búsqueda para esa
ejecución del procedimiento
Esta opción se puede usar cuando se ejecuta
cualquier procedimiento almacenado
Sintaxis simplificada:
[exec | execute] procedure_name with
recompile
Ejemplo:
execute proc_update_titles with recompile
Bases de Datos - 2007
Trigger
Un trigger es un procedimiento almacenado asociado
con una tabla, el cual se ejecuta automáticamente
cuando se modifica un dato de esa tabla
User-Defined
Can It Be
Can It Be
Can It Use
Explicitly
Executed
Parameters?
Called?
Automatically?
Yes
No
Yes
No
Yes
No
Stored
Procedure
Trigger
Bases de Datos - 2007
Aplicaciones Típicas de triggers
Hacer modificaciones en cascada sobre tablas
relacionadas
Deshacer cambios que violan la integridad de los
datos
Forzar restricciones que son muy complejas para
reglas y restricciones
Mantener datos duplicados
Mantener columnas con datos derivados
Hacer ajustes de registros
Bases de Datos - 2007
Definición de un trigger
Un trigger se define asociado con una tabla para una o
más sentencias de manipulación de datos
Un trigger se puede definir para insert, update, o delete o
cualquier combinación de ellos
Bases de Datos - 2007
Activación de un trigger
Cuando se modifica un dato en una tabla que tiene
declarado un trigger para esa sentencia, el trigger se
“dispara”
El trigger se dispara una vez, independientemente del
número de filas afectadas
El trigger se dispara aunque no hayan filas afectadas
Bases de Datos - 2007
Triggers and transacciones
Un trigger es parte de la transacción que causa el
disparo
El trigger puede deshacer:
Así mismo solamente
Así mismo y la sentencia que causa el disparo
La transacción total
Bases de Datos - 2007
Reglas para triggers
Los triggers pueden:
Declarar variables locales
Invocar procedimientos almacenados
Los triggers no pueden:
Llamarse directamente
Usar parámetros
Definirse sobre tablas temporales o vistas
Crear objetos permanentes de base de datos
Las operaciones con registro mínimo (como select
into) no disparan los triggers
Bases de Datos - 2007
Crear triggers
Sintaxis simplificada:
create trigger trigger_name
on table_name
for {insert | update | delete} [, {insert | update | delete} ...]
as
sql_statements
Bases de Datos - 2007
Crear triggers - Oracle
Sintaxis simplificada:
CREATE [OR REPLACE] TRIGGER <nombre_trigger>
{BEFORE|AFTER}
{DELETE|INSERT|UPDATE [OF col1, col2, ..., colN]
[OR {DELETE|INSERT|UPDATE [OF col1, col2, ..., colN]...]}
ON <nombre_tabla>
[FOR EACH ROW [WHEN (<condición>)]]
DECLARE
-- variables locales
BEGIN
-- Sentencias
[EXCEPTION]
-- Sentencias control de excepcion
END <nombre_trigger>;
Bases de Datos - 2007
Borrar Triggers
Sintaxis simplificada:
drop trigger trigger_name
Ejemplo:
drop trigger trg_i_sales
Bases de Datos - 2007
Procedimientos del sistema para procedimientos
almacenados
sp_depends {table_name | trigger_name}
Cuando se da el nombre de tabla, lista todos
los objetos (incluyendo triggers) de la misma
base de datos
Cuando se da el nombre de trigger, lista todas
las tablas referencias
sp_help trigger_name
Muestra información del trigger
sp_helptext trigger_name
Muestra el código usado para crear el trigger
sp_rename old_trigger_name, new_trigger_name
Cambia el nombre del trigger
Bases de Datos - 2007
Las tablas inserted y deleted
inserted y deleted son dos tablas que se crean automáticamente
cada vez que se dispara un trigger
inserted almacena cualquier fila que se vaya a añadir a la tabla
deleted almacena cualquier fila que se vaya a borrar de la tabla
Bases de Datos - 2007
:old :new en Triggers Oracle
Sentencia SQL
OLD
NEW
Insert
No definido; todos los
campos toman valor
NULL.
Valores que serán
insertados cuando se
complete la orden.
Update
Valores originales de la
fila, antes de la
actualización.
Nuevos valores que
serán escritos cuando
se complete la orden.
Delete
Valores, antes del
borrado de la fila.
No definidos; todos los
campos toman el valor
NULL.
Bases de Datos - 2007
Borrados
A delete adds rows to the deleted table
Bases de Datos - 2007
Inserciones
An insert adds rows to the inserted table
Bases de Datos - 2007
Actualizaciones
An update adds rows to both tables
Bases de Datos - 2007
Reglas para las tablas inserted y deleted
Ambas tablas tienen las mismas columnas que la
tabla asociada al trigger
El trigger puede consultar datos de las dos tablas
Otros procesos no pueden consultar datos de las dos
tablas
El trigger no puede modificar datos en las dos tablas
Cada anidamiento de triggers tiene sus propias tablas
inserted y deleted
Si un trigger modifica datos de su tabla asociada, esos
cambios no se reflejan en las tablas inserted and deleted de
ese trigger
Bases de Datos - 2007
Triggers y rollbacks
Tres tipos de rollbacks:
Deshacer el trigger
Deshacer el trigger y la sentencia que lo
disparó
Deshacer toda la transacción
Bases de Datos - 2007
Deshacer un trigger
rollback trigger deshace el trigger y la sentencia que lo
disparó
Sintaxis:
rollback trigger [with raiserror error_number
[error_statement] ]
Bases de Datos - 2007
Prácticas recomendadas al hacer Triggers
Las siguientes consideraciones se deben hacer al
elaborar triggers:
@@rowcount
if update
triggers anidados
triggers recursivos
Bases de Datos - 2007
if update
if update es una condición que le permite a un trigger
chequear si ha habido un cambio en una determinada
columna
Sólo se puede usar en triggers
Usualmente se usa para chequear si el valor de una
llave primaria ha cambiado
Sintaxis simplificada:
if update (column_name) [ {and | or} update
(column_name)]...
Bases de Datos - 2007
Triggers anidados
Un trigger anidado es un trigger que se dispara en respuesta a una
modificación hecha en un trigger
Nivel máximo de anidamiento: 16
Tanto los procedimientos almacenados como los triggers cuentan
en la determinación del nivel máximo
@@nestlevel retorna el nivel de anidamiento
Bases de Datos - 2007
Triggers recursivos
Un trigger recursivo es aquel que se dispara cuando modifica su
propia tabla
Por default, un trigger que modifica su propia tabla no causa un
disparo recursivo del trigger
Bases de Datos - 2007
Métodos para integridad de datos
Dos métodos para implementar integridad de datos
Domain
Integrity
Entity Integrity
Referential
Integrity
Constraints
Check
constraints
Primary key
constraints,
unique
constraints
References
constraints
Database
Objects
Rules
Indexes
Triggers
Bases de Datos - 2007
Actualización de valores llave
Acción deseada
Restricciones
Triggers
Insertarar valor de llave primaria
Permitido
Permitido
Insertar valor de llave foránea
Permitido
Permitido
Actualizar valor de llave primaria
No permitido*
Permitido
Actualizar valor de llave foránea
Permitido
Permitido
Borrar valor de llave primaria
No permitido*
Permitido
Borrar valor de llave foránea
Permitido
Permitido
*Valores de llaves primarias se pueden actualizar o borrar si no están
referencidos en llaves foráneas
Solamente en triggers es posible borrar o actualizar una llave
primaria
Sólo en triggers es posible hacer cambios en cascada
Bases de Datos - 2007
Restricciones vs triggers
Ventajas de las restricciones:
Las restricciones (y reglas) son más rápidas que los
triggers
Las restricciones no requieren codificación adicional
Es mejor para chequear datos antes de ingresarlos a la
base de datos
Ventajas de los triggers:
Muy flexible
Los triggers pueden hacer cualquier cosa que se pueda
codificar
Mejor para las reglas complejas del negocio que no se
pueden expresar como restricciones referenciales tales como
actualizaciones o borrados en cascada
Bases de Datos - 2007
Preguntas
Gracias por su Atención
Bases de Datos - 2007
Descargar