Pa Triggers

Embed Size (px)

Citation preview

  • Procedimientos almacenados, triggers

  • Procedimientos almacenadosUn procedimiento almacenado es un conjunto de sentencias SQL y de control de flujoBeneficios de los procedimientos almacenados:Simplifican la ejecucin de tareas repetitivasCorren ms rpido que las mismas instrucciones ejecutadas en forma interactivaReducen el trfico a travs de la redPueden capturar errores antes que ellos puedan entrar a la base de datosEstablece consistencia porque ejecuta las tareas de la misma formaPermite el desarrollo modular de aplicacionesAyuda a proveer seguridadPuede forzar reglas y defaults complejos de los negocios

  • Tipos de procedimientos almacenadosProcedimientos almacenados definidos por el usuarioSon procedimientos definidos por el usuario que se deben llamar explcitamente TriggersSon procedimientos definidos por el usuario que se ejecutan automticamente cuando se modifica un dato en una tabla Procedimientos del sistemaProcedimientos suministrados por el sistema Procedimientos extendidosProcedimientos que hacen llamadas al sistema operativo y ejecutan tareas a ese nivel

  • Interactive Execution

  • Creacin de un procedimiento almacenado

  • Ejecucin de un procedimiento almacenado

  • Ventajas en el rendimientoUn procedimiento almacenado se ejecuta ms rpido que un batch porque:El procedimiento almacenado ya ha sido analizadoYa se han resuelto las referencias a los objetos referenciados en el procedimiento almacenadoNo se necesita construir el rbol de bsqueda, l usa el que se hace en el momento de compilarloNo se necesita crear un plan de bsqueda, porque ya el procedimiento tiene uno

  • Crear y borrar procedimientos almacenadosSintaxis simplificada para create:create proc procedure_nameasstatementsreturnEjemplo:create proc proc_update_titlesasupdate titlesset price = price * $0.95where total_sales < 3000returnSintaxis simplificada para drop:drop proc procedure_nameEjemplo:drop proc proc_update_titles

  • Ejecutar procedimientos almacenadosSintaxis simplificada:[exec | execute] procedure_nameEjemplo:execute proc_update_titles

  • VariablesLos procedimientos almacenados pueden crear y usar variables localesLas variables slo existen mientras exista el procedimientoLas variables no las puede usar otro procesoEjemplo:create proc proc_update_under_half_titlesasdeclare @max_sales int, @half_max realselect @max_sales = max(total_sales)from titlesselect @half_max = @max_sales / 2select title, total_sales from titleswhere total_sales < @half_maxupdate titlesset price = price * $0.95where total_sales < @half_maxreturn

  • Sentencias vlidas e invlidasUn procedimiento almacenado puede:Seleccionar y modificar datosCrear tablas temporales y permanentesLlamar otros procedimientos almacenadosReferenciar objetos de bases de datosUn procedimiento almacenado no puede ejecutar:use databasecreate viewcreate defaultcreate rulecreate procedurecreate trigger

  • Procedimientos almacenados y permisosPara permitir que otros usen un procedimiento almacenado, el propietario debe dar los respectivos permisosSintaxis simplificada:grant executeon procedure_nameto user_listEjemplo:grant executeon proc_update_titlesto tjovanka, vturlough, pbrown

  • Crear procedimientos almacenadosCrear un procedimiento almacenado sencillo:create proc proc_helloasprint "Hello, "returnVer el cdigo fuente de un procedimiento:sp_helptext proc_helloEjecutar el procedimiento:exec proc_helloBorrar los objetos de bases de datos:drop proc proc_hello

  • Parmetros de entradaAn input Parmetro is a variable local to a procedimiento almacenado that can receive a value from the exec procedure Sentencia

  • Definir parmetros de entradaSintaxis simplificada:create procedure procedure_name(parameter_name datatype default_value[, parameter_name datatype default_value...] )asstatementsreturnEjemplo:create proc proc_author_info(@lname varchar(40), @fname varchar(20))as-- lists the author and his or her booksselect au_lname, au_fname, titlefrom authors, titles, titleauthorwhere au_fname = @fnameand au_lname = @lnameand authors.au_id = titleauthor.au_idand titles.title_id = titleauthor.title_idreturn

  • Pasar parmetrosDos mtodos para pasar valores a parmetros:Paso de parmetros por posicinPaso de parmetros por nombre

  • Paso de parmetros por posicinSintaxis para paso por posicin:[exec | execute] procedure_name value [, value...]Ejemplo:exec proc_author_info "Ringer", "Albert"

    au_lnameau_fnametitle---------------------RingerAlbertIs Anger the Enemy?RingerAlbertLife Without Fear

    Los parmetros se deben pasar en el mismo orden en que ellos aparecen en la sentencia create procedureComo este mtodo es ms propenso a errores, se aconseja el paso por nombre

  • Paso de parmetros por nombreSintaxis para paso por nombre:[exec | execute] procedure procedure_nameparameter_name = value [, parameter_name = value ]Ejemplo:exec proc_author_info@lname = "Ringer", @fname = "Albert"

    au_lnameau_fnametitle---------------------RingerAlbertIs Anger the Enemy?RingerAlbertLife Without FearLos nombres de los parmetros en la sentencia exec deben concordar con los nombres de los parmetros usados en la sentencia create procedureLos parmetros pueden pasar en cualquier orden

  • Valores por defaultSe puede asignar un valor por default a un parmetro cuando l no se indica en la sentencia execEjemplo:create proc proc_state_authors(@state char(2) = "CA")asselect au_lname, au_fname, statefrom authorswhere state = @statereturn

    exec proc_state_authors-- No state value passed

    au_lnameau_fnamestate---------------------WhiteJohnsonCAGreenMarjorieCA...

  • Parmetros de entrada: errores comunesLos valores que se pasan no tienen el mismo tipo de datos que los parmetros definidosEn la misma sentencia, se pasa un parmetro por posicin despus de haber pasado un parmetro por nombreAunque no es recomendado, es posible mezclar los dos mtodos para pasar valores, sin embargo, despus de pasar un valor a un parmetro por nombre, todos los restantes de deben pasar por nombreOlvido de uno o ms parmetrosEl olvido de uno o ms valores para los parmetros, hace que se usen los valores por defaultLos valores para los parmetros se pasan en un orden errado

  • Parmetros de entrada: Ejemplocreate procedure proc_insert_sale (@stor_idchar(4)= NULL, @ord_num varchar(20)= NULL, @datedatetime= NULL)as/* If no date is passed, use the current date. */if (@date is NULL) begin select @date = getdate() endbegin transaction/* insert sales order */insert sales (stor_id, ord_num, date)values (@stor_id, @ord_num, @date)if @@error 0beginrollback transactionraiserror 24001 "Transaction failed"returnendcommit transactionreturn

  • Parmetros de entradaCrear un procedimiento almacenado que tenga un parmetro de entrada:create proc proc_hello_param (@name varchar(30))asprint "Hello %1!", @namereturnEjecutar el procedimiento con y sin un valor para el parmetro de entrada. Una sentencia fallar:exec proc_hello_paramexec proc_hello_param ""Crear un procedimiento almacenado que tiene un valor por default para un parmetro de entrada:create proc proc_hello_def(@name varchar(30) = "whoever you are")asprint "Hello %1!", @namereturn

  • Parmetros de entradaEjecutar el procedimiento con y sin un valor para el parmetro de entrada:exec proc_hello_defexec proc_hello_def ""Cul procedimiento almacenado parece ser ms amigable?

    Borrar los objetos de bases de datos creados:drop proc proc_hello_param, proc_hello_def

  • Retorno de valoresA return Parmetro is a variable local to a procedimiento almacenado that can send a value to the exec procedure Sentencia

  • Crear parmetros que retornan valoresSintaxis simplificada:create procedure procedure_name(parameter_name datatype output[, parameter_name datatype output...] )asstatementsreturnEjemplo:create proc proc_new_price(@title_id char(6), @new_price money output)asselect @new_price = pricefrom titleswhere title_id = @title_idselect @new_price = @new_price * $1.15return

  • Usar parmetros que retornan valoresSintaxis simplificada:[exec | execute] procedure_name variable outputEjemplo:declare @my_title char(6), @my_price moneyselect @my_title = "PC8888"exec proc_new_price@my_title, @my_price output

    ----------23.00

    Los valores que retornan los parmetros se pasan automticamente al conjunto respuestaEl retorno de valores se pueden pasar por nombre o por posicinSe recomienda el paso por nombre

  • Lmite de anidamiento para procedimientosLos procedimientos almacenados pueden llamar otros procedimientos almacenadosEl mximo nivel de anidamiento es 16La variable @@nestlevel contiene el nivel de anidamiento actualSi se excede el nivel mximo:Se abortan los procedimientos pendientesEl servidor retorna un error

  • Planes de bsquedaUn plan de bsqueda es un conjunto ordenado de etapas que se requieren para acceder los datos, incluyendo informacin sobre:Si usar o no un ndiceEl ndice a usarEl orden en el cual las tablas se deben encadenarLos planes de bsqueda son creados por el optimizador de bsquedasEl optimizador de bsquedas usa informacin acerca de los objetos de base de datos para producir el planLos planes de bsqueda creados para los procedimientos, se reutilizanCuando se ejecuta un procedimiento almacenado, el servidor chequea el cach del procedimiento para un plan no usadoSi hay un plan de bsqueda no utilizado, el servidor lo usaSi no hay un plan de bsqueda no utilizado, el servidor genera uno nuevo del rbol de bsqueda en sysprocedures

  • Planes de bsqueda sub-ptimosEl plan de bsqueda creado para la una ejecucin de un procedimiento almacenado puede que no sea el plan de bsqueda ptimo para la siguiente ejecucin del procedimiento almacenadoLas dos ejecuciones pueden usar parmetros de entrada muy diferentesSe pueden haber aadido nuevos ndices entre las dos ejecucionesEl tamao de las tablas accedidas pueden haber cambiado significativamente entre las dos ejecucionesHay tres formas para forzar al servidor a generar un nuevo plan de bsquedaUsar with recompile en el procedimientoUsar with recompile cuando se ejecute el procedimientoUsar sp_recompile

  • Crear procedimientos con recompileEn un procedimiento, usar la opcin with recompile para forzar al servidor a crear un nuevo plan de bsqueda cada vez que se ejecute el procedimientoSintaxis simplificada:create proc procedure_namewith recompileasstatementsreturn

  • Crear procedimientos con recompileEjemplo:create proc proc_list_California_authors(@early_name varchar(80), @late_name varchar(80))with recompileasselect au_id, au_lname, au_fnamefrom authorswhere au_lname between @early_name and @late_nameand state = "CA"order by au_lnamereturn

  • Ejecucin de procedimientos with recompileCuando se ejecute un procedimiento almacenado, usar la opcin with recompile para forzar al servidor a crear un nuevo plan de bsqueda para esa ejecucin del procedimientoEsta opcin se puede usar cuando se ejecuta cualquier procedimiento almacenadoSintaxis simplificada:[exec | execute] procedure_name with recompileEjemplo:execute proc_update_titles with recompile

  • sp_recompilesp_recompile hace que cada procedimiento almacenado (y trigger) que utilice la tabla indicada se recompile la siguiente vez que l se ejecuteSintaxis:sp_recompile table_nameEjemplo:sp_recompile authors

  • TriggerUn trigger es un procedimiento almacenado asociado con una tabla, el cual se ejecuta automticamente cuando se modifica un dato de esa tabla

    Can It Be

    Explicitly

    Called?

    Can It Be

    Executed

    Automatically?

    Can It Use

    Parameters?

    User-Defined

    Stored

    Procedure

    Yes

    No

    Yes

    Trigger

    No

    Yes

    No

  • Aplicaciones Tpicas de triggersHacer modificaciones en cascada sobre tablas relacionadasDeshacer cambios que violan la integridad de los datosForzar restricciones que son muy complejas para reglas y restriccionesMantener datos duplicadosMantener columnas con datos derivadosHacer ajustes de registros

  • Definicin de un triggerUn trigger se define asociado con una tabla para una o ms sentencias de manipulacin de datosUn trigger se puede definir para insert, update, o delete o cualquier combinacin de ellos

  • Activacin de un triggerCuando se modifica un dato en una tabla que tiene declarado un trigger para esa sentencia, el trigger se disparaEl trigger se dispara una vez, independientemente del nmero de filas afectadasEl trigger se dispara aunque no hayan filas afectadas

  • Triggers and transaccionesUn trigger es parte de la transaccin que causa el disparoEl trigger puede deshacer:As mismo solamenteAs mismo y la sentencia que causa el disparoLa transaccin total

  • Reglas para triggersLos triggers pueden:Declarar variables localesInvocar procedimientos almacenadosLos triggers no pueden:Llamarse directamenteUsar parmetrosDefinirse sobre tablas temporales o vistasCrear objetos permanentes de base de datosLas operaciones con registro mnimo (como select into) no disparan los triggers

  • Crear triggersSintaxis simplificada:create trigger trigger_nameon table_namefor {insert | update | delete} [, {insert | update | delete} ...]assql_statementsEjemplo:create trigger trg_i_saleson salesfor insertas if datename (dd,getdate()) = "Sun"begin raiserror 40070, "Sales cannot be processed on Sunday." rollback triggerend

  • Borrar TriggersSintaxis simplificada:drop trigger trigger_nameEjemplo:drop trigger trg_i_sales

  • Procedimientos del sistema para procedimientos almacenadossp_depends {table_name | trigger_name}Cuando se da el nombre de tabla, lista todos los objetos (incluyendo triggers) de la misma base de dtosCuando se da el nombre de trigger, lista todas las tablas referenciassp_help trigger_nameMuestra informacin del triggersp_helptext trigger_nameMuestra el cdigo usado para crear el triggersp_rename old_trigger_name, new_trigger_nameCambia el nombre del trigger

  • Triggers - ejemploCrear dos tablas:select * into myauthorsfrom pubs2..authorscreate table myrecord (mytimedatetime,myrowsint)Crear un trigger que guarde la fecha y nmero de filas afectadas por cada delete:create trigger trg_d_myauthorson myauthorsfor deleteasinsert into myrecordvalues (getdate(), @@rowcount)return

  • Triggers - ejemploEjecutar un delete y ver la tabla myrecords:delete from myauthorswhere state = "CA" select * from myrecordEjecutar un delete que no afecta filas y ver la tabla myrecords :delete from myauthorswhere 1 = 2select * from myrecordBorrar los objetos de base de datos creados:drop table myauthors, myrecord

  • Las tablas inserted y deletedinserted y deleted son dos tablas que se crean automticamente cada vez que se dispara un triggerinserted almacena cualquier fila que se vaya a aadir a la tabladeleted almacena cualquier fila que se vaya a borrar de la tabla

  • BorradosA delete adds rows to the deleted table

  • Uso de la tabla deleted - ejemplocreate trigger trg_d_publisherson publishers for deleteas-- Exit trigger if no rows were modified.if @@rowcount = 0return

    -- For deleted publishers, delete -- corresponding titles delete titles from titles t, deleted dwhere t.pub_id = d.pub_id-- Appropriate actions would take place here -- since a deleted publisher has far-reaching -- effects throughout the database. return

  • InsercionesAn insert adds rows to the inserted table

  • Uso de la tabla inserted - ejemplo-- Make sure all au_ids matchif (select count(*) from authors a, inserted iwhere a.au_id=i.au_id ) @num_rowsbeginraiserror 31114 "Attempt to insert invalid au_id into titleauthor."rollback transactionreturnendreturngo

  • Uso de la tabla inserted - ejemplo-- Insert and update trigger on titleauthorcreate trigger trg_iu_titleauthoron titleauthorfor insert, update as-- Find out how many rows were modifieddeclare @num_rows intselect @num_rows=@@rowcountif @num_rows=0return-- Make sure all title_ids matchif (select count(*) from titles t, inserted iwhere t.title_id=i.title_id) @num_rowsbeginraiserror 31113 "Attempt to insert invalid title_id into titleauthor."rollback transactionreturnend

  • ActualizacionesAn update adds rows to both tables

  • Uso de las tablas inserted y deleted-- Insert, update, and delete trigger on salesdetailcreate trigger trig_iud_salesdetailon salesdetailfor insert, update, deleteas

    -- Exit trigger if no rows were modified.if @@rowcount = 0return

  • Uso de las tablas inserted y deleted-- If a new quantity has been inserted or updated for a-- given title_id, add the value to titles.total_sales. The-- isnull function is used because titles.total_sales might-- be NULL.

    update titlesset total_sales = isnull(total_sales, 0) +(select sum(qty)from insertedwhere titles.title_id = inserted.title_id)where title_id in (select title_id from inserted)

  • Uso de las tablas inserted y deleted-- If an old quantity has been updated or deleted for a-- given title_id, subtract the value from-- titles.total_sales. The isnull function is used because-- titles.total_sales might be NULL.

    update titlesset total_sales = isnull(total_sales, 0) -(select sum(qty)from deletedwhere titles.title_id = deleted.title_id)where title_id in (select title_id from deleted)

    return

  • Reglas para las tablas inserted y deletedAmbas tablas tienen las mismas columnas que la tabla asociada al triggerEl trigger puede consultar datos de las dos tablasOtros procesos no pueden consultar datos de las dos tablasEl trigger no puede modificar datos en las dos tablasCada anidamiento de triggers tiene sus propias tablas inserted y deletedSi un trigger modifica datos de su tabla asociada, esos cambios no se reflejan en las tablas inserted and deleted de ese trigger

  • Tablas inserted and deleted - ejemploCrear una tabla:select * into myauthorsfrom pubs2..authorsCrear un trigger que use la funcin suser_name( ) para listar la(s) fila(s) que se borraron y el nombre del usuario:create trigger trg_d_myauthorson myauthorsfor deleteasselect suser_name(), "deleted these rows:"select * from deletedreturnEjecutar un delete que afecte ms de una fila:delete from myauthorswhere state = "CA"

  • Tablas inserted and deleted - ejemploEjecutar un delete que no afecte filas:delete from myauthorswhere 1 = 2Borrar los objetos de base de datos:drop table myauthors

  • Triggers y rollbacksTres tipos de rollbacks:Deshacer el triggerDeshacer el trigger y la sentencia que lo disparDeshacer toda la transaccin

  • Deshacer un triggerPara deshacer un trigger, declarar un punto de grabacin y luego hacer el rollbackUn rollback sin punto de grabacin deshace toda la transaccin

  • Deshacer un triggerrollback trigger deshace el trigger y la sentencia que lo disparSintaxis:rollback trigger [with raiserror error_number [error_statement] ]Ejemplo:create trigger trg_i_publisherson publishersfor insertasif @@rowcount > 1begin rollback trigger with raiserror 40031"You cannot insert more than one publisher at a time." returnend

  • Deshacer un trigger

  • Deshacer una transaccin Procedimiento almacenadoCase Dbegin tran ... insert ... print "in sp" ... commit tran print "sp done"Trigger begin tran... rollback tranprint "tr donereturnPara deshacer toda la transaccin donde est inmerso el trigger, ejecutar un rollback sin un punto de grabacin Procedimiento almacenadoCase Ebegin tran ... insert ... print "in sp" ... commit tran print "sp done"Trigger.... .... Rollback tranprint tr donereturn

  • Triggers anidadosUn trigger anidado es un trigger que se dispara en respuesta a una modificacin hecha en un trigger

    Nivel mximo de anidamiento: 16Tanto los procedimientos almacenados como los triggers cuentan en la determinacin del nivel mximo@@nestlevel retorna el nivel de anidamiento

  • Triggers recursivosUn 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

  • Mtodos para integridad de datosDos mtodos 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

  • Actualizacin de valores llave

    *Valores de llaves primarias se pueden actualizar o borrar si no estn referencidos en llaves forneas

    Solamente en triggers es posible borrar o actualizar una llave primariaSlo en triggers es posible hacer cambios en cascada

    Accin deseada

    Restricciones

    Triggers

    Insertarar valor de llave primaria

    Permitido

    Permitido

    Insertar valor de llave fornea

    Permitido

    Permitido

    Actualizar valor de llave primaria

    No permitido*

    Permitido

    Actualizar valor de llave fornea

    Permitido

    Permitido

    Borrar valor de llave primaria

    No permitido*

    Permitido

    Borrar valor de llave fornea

    Permitido

    Permitido

  • Restricciones vs triggersVentajas de las restricciones:Las restricciones (y reglas) son ms rpidas que los triggersLas restricciones no requieren codificacin adicionalEs mejor para chequear datos antes de ingresarlos a la base de datosVentajas de los triggers:Muy flexibleLos triggers pueden hacer cualquier cosa que se pueda codificarMejor para las reglas complejas del negocio que no se pueden expresar como restricciones referenciales tales como actualizaciones o borrados en cascada