P. 1
Guia 2 SQL Server

Guia 2 SQL Server

|Views: 134|Likes:
Published by Mario Benitez

More info:

Published by: Mario Benitez on Mar 21, 2012
Copyright:Attribution Non-commercial

Availability:

Read on Scribd mobile: iPhone, iPad and Android.
download as PDF, TXT or read online from Scribd
See more
See less

05/30/2012

pdf

text

original

Tema: Procedimientos almacenados y cursores.

Facultad : Ingeniería Escuela : Computación Asignatura: SQL SERVER

GUÍA 2 Pág.

1

Transact-SQL se utiliza a menudo en la creación de procedimientos almacenados y triggers de tal forma que las aplicaciones clientes que se conectan a SQL Server solo se preocupan por la presentación de los datos para el usuario final. Las variables locales se declaran al inicio de un proceso por lotes o un procedimiento almacenado. mientras que la lógica de los procesos se maneja en el servidor. Variables: Las variables locales se identifican como aquellos objetos que comienzan con el carácter arroba '@' una vez. bucles.ELSE GOTO etiqueta WAITFOR Descripción Define una decisión.. las variables globales se identifican como los objetos que tienen 2 arrobas al inicio '@@'. la forma de asignarle valores a una variable es con la instrucción SELECT. Acompaña al bucle WHILE y le indica continuar con la siguiente iteración. @@error. El tiempo puede ser un intervalo de retardo o un instante especificado de ejecución (una hora concreta del día) Bucle básico de SQL Acompaña al bucle WHILE y le indica finalizarlo inmediatamente. decisiones. OBJETIVOS Utilizar procedimientos almacenados Conocer el uso de los cursores Realizar operaciones utilizando transacciones II. Salida incondicional del procedimiento o GUÍA 2 Pág. Define un salto incondicional Establece un tiempo para la ejecución de una instrucción. WHILE BREAK CONTINUE RETURN [n] 2 . como ejemplo de variables globales tenemos: @@rowcount. INTRODUCCIÓN  Programación con Transact-SQL Transact-SQL no es realmente un lenguaje de programación similar a las herramientas de tercera y cuarta generación sin embargo permite utilizar SQL para realizar tareas complejas que requieren saltos.I. El control de flujo en Transact-SQL Construcción IF.

la sintaxis es: PRINT "cadena" . asumirá 5000. Por ello surge una pregunta: ¿Cómo puedo proporcionar a los usuarios la velocidad y eficiencia que necesitan y merecen? Esa herramienta diseñada principalmente para optimizar la obtención de datos.  Creación de procedimientos almacenados (Store Procedures) La instrucción general para crear procedimientos almacenados es la siguiente: CREATE PROC nombre_proc parametros GUÍA 2 Pág. Dos de las cuestiones más importantes para el usuario de bases de datos son la velocidad y la eficiencia.END CASE proceso por lotes. cadena puede ser también una variable de tipo varchar...ELSE o WHILE para agrupar un conjunto de instrucciones. argumento1 [. Implementada en la instrucción SELECT y UPDATE y permite realizar consultas y actualizaciones condicionales. Procedimientos almacenados. Por ejemplo: PRINT „Hola a todos‟ RAISERROR Es similar a PRINT. Un procedimiento almacenado es una consulta que se almacena en una base de datos en SQL Server en lugar de almacenarse en el código cliente (normalmente C# o Java) en el equipo cliente. RAISERROR también permite que los errores se registren en el servicio de sucesos de Windows NT haciendo posible leerlos a través del visor de sucesos de Windows NT. es el procedimiento almacenado. se puede definir un número entero como estado devuelto y puede asignarse a cualquier variable. severidad. pero permite especificar un número de error y la severidad del mensaje. La sintaxis es: RAISERROR({id_mensaje | cadena_mensaje}. 3 . PRINT Es una instrucción para imprimir un dato en la pantalla.BEGIN. Después de llamar a RAISERROR. si no se pasa ningún id_mensaje. la variable global @@ERROR tendrá el valor de id_mensaje. Utilizado en conjunto con IF. estado [.argumento2]]) WITH LOG.

ShowProduct Nota: los procedimientos almacenados los puede encontrar en la base de datos donde los trabaja. Ejemplo2: --Obteniendo Ganancia sobre las ventas CREATE PROC Ganancia_de_Venta @id_Venta int. ListPrice.Product WHERE SellStartDate > '1/1/2003' ORDER BY SellStartDate. Name GO Para probar el nuevo procedimiento. -. abra una nueva consulta de SQL Server y escriba y ejecute el código siguiente. en la opción programación.Product WHERE SellStartDate > '1/1/2003' ORDER BY SellStartDate. que un procedimiento almacenado puede recibir parámetros de entrada y devolver parámetros de salida. Name Procedimiento con instrucción anterior CREATE PROCEDURE Production.parametro de entrada @id_Prod_bodega int. Color.2) OUTPUT -. 4 . SellStartDate FROM Production.parametro de entrada @ganancia decimal (8. -. ListPrice.ShowProduct AS Select name. USE AdventureWorks EXEC Production.AS INSTRUCCION SQL Es necesario aclarar.parametro de salida AS declare @unidades int --Asignando un valor a la variable unidades SELECT @unidades = unidades FROM detalleventa WHERE idventa=@id_Venta AND idprodbod=@id_Prod_bodega SELECT @ganancia = (preciov-precioc)*@unidades FROM bodega WHERE idprodbod=@id_Prod_bodega GO GUÍA 2 Pág. Color. Ejemplo 1 Instrucción SQL USE AdventureWorks Select name. SellStartDate FROM Production.

El número máximo de variables locales en un procedimiento almacenado está limitado únicamente por la memoria disponible. sin embargo muchas veces es necesario utilizar no el enfoque de conjunto de datos sino de registros para realizar ciertas operaciones no complejas. GUÍA 2 Pág. es donde se implementan los cursores. Procedimientos almacenados del sistema Muchas de las actividades administrativas de SQL Server se realizan mediante un tipo especial de procedimiento denominado procedimiento almacenado del sistema. Si ejecuta un procedimiento almacenado que llama a otro procedimiento almacenado. con el prefijo sp_ (stored procedure). excepto las siguientes instrucciones CREATE. cabe citar las siguientes: La propia definición CREATE PROCEDURE puede incluir cualquier número y tipo de instrucciones SQL. sp_droplogin. 5 .Reglas de procedimientos almacenados Entre las reglas para la programación de procedimientos almacenados. que no pueden ser utilizadas nunca dentro de un procedimiento almacenado: CREATE DEFAULT CREATE PROCEDURE CREATE RULE CREATE TRIGGER CREATE VIEW Se puede crear otros objetos de base de datos dentro de un procedimiento almacenado. Un cursor es un conjunto de resultados donde existe la posibilidad de desplazarse registro por registro en cualquier dirección. Puede hacer referencia a un objeto creado en el mismo procedimiento almacenado. El número máximo de parámetros en un procedimiento almacenado es de 1. por ejemplo una instrucción SELECT regresa un conjunto de datos. Los procedimientos almacenados del sistema se crean y se almacenan en la base de datos master. etc. Cursores Una base de datos relaciona como SQL Server está orientada a conjuntos de manera natural. siempre que se cree antes de que se haga referencia al objeto. el procedimiento al que se llama puede tener acceso a todos los objetos creados por el primer procedimiento. incluidas las tablas temporales. Por ejemplo: sp_help.024. Estos procedimientos se pueden ejecutar desde cualquier base de datos. sp_heldb. Puede hacer referencia a tablas temporales dentro de un procedimiento almacenado.

se utiliza la instrucción UPDATE / DELETE tabla WHERE CURRENT OF nombre_cursor. como es una relación de muchos a muchos se tiene una tercera tabla llamada "catalogo" donde se indica el detalle del producto. abrirlos. Para cerrar el cursor.Trabajar con cursores implica algunos pasos básicos como son el declararlos. MATERIAL Y EQUIPO A UTILIZAR Guía de Laboratorio Nº 2 de SQL Server Computadora con SQL SERVER 2005 Disquete o memoria USB IV. sin embargo el costo del producto comprado por el almacén puede variar y el almacén registra el precio de costo y de venta de los productos GUÍA 2 Pág. se debe considerar lo siguiente: - - - Para declarar un cursor se utiliza la instrucción DECLARE.. vuelve a adquirir nuevos productos. Esta base de datos se desea para un almacén que tiene varios productos a la venta. así si @@ FETCH_STATUS = 0 la captura fue un éxito. para ello se plantea la siguiente base de datos: Definición. existe una variable global llamada @@FETCH_STATUS que indica el estado de la última instrucción FETCH. capturar filas en el cursor. Para liberar la memoria. Lo interesante es que el almacén adquiere productos a cierto precio y los almacena en bodega. se utiliza la instrucción DEALLOCATE. III. opcionalmente se puede modificar o eliminar registros. Para abrir el cursor se utiliza la instrucción OPEN Para capturar filas de un cursor se utiliza la instrucción FETCH. y a medida que las existencias del producto van disminuyendo. es necesario declarar variables e indicarle a FETCH cuales son las variables. PROCEDIMIENTO En esta práctica utilizaremos los procedimientos almacenados. se utiliza la instrucción: CLOSE. Cuando se crean cursores. los cuales adquiere de varios proveedores. 6 . luego se debe cerrar el cursor y por ultimo retirarlo de la memoria. Un producto puede ser distribuido por varios proveedores y un proveedor distribuye varios productos. cursores y transacciones utilizando la base de datos de SQL Server 2005. si @@ FETCH_STATUS = -1 no hay mas filas (se ha llegado al inicio o al final) y si @@FETCH_STATUS = -2 significa que la fila ya no existe en el cursor (probablemente se eliminó). Para actualizar o eliminar el registro que esta siendo apuntado por el cursor.

nombre char(60) not null. idproveedor char(8) not null. constraint pk_idproducto primary key (idproducto) ) create table catalogo ( idprodcat char(16) not null. Para poder crear la base de datos anterior. deberá crear una base de datos con el nombre almacen_carnet. 7 . constraint pk_idproveedor primary key (idproveedor) ) create table producto ( idproducto char(8) not null. precio decimal(8. idproducto char(8) not null. constraint pk_idprodcat primary key clustered (idprodcat).creacion de las tablas create table proveedor ( idproveedor char(8) not null. GUÍA 2 Pág.adquiridos en una compra y maneja la política de vender primero los productos más antiguos. nombre char(60) not null. y ejecute los scripts para generar las tablas que se listan a continuación: -.2) not null.

-. idcliente char(8) not null. constraint fk_idcliente foreign key (idcliente) references cliente(idcliente) ) create table detalleventa ( idventa integer not null. -.idproveedor). constraint fk_idproducto foreign key (idproducto) references producto(idproducto). fecha datetime not null.2) not null. constraint pk_idventa primary key (idventa). constraint ck_idprodcat_catalogo check (idprodcat=idproducto+idproveedor) ) create table bodega ( idprodbod integer not null identity. constraint fk_idprodcat foreign key (idprodcat) references catalogo(idprodcat). 8 . constraint ck_unidades_detalleventa check (unidades>0) ) Ejecute las siguientes instrucciones SQL para introducir datos a las tablas de trabajo: GUÍA 2 Pág.2) not null. constraint ck_precios_bodega check (precioc >=0 and preciov >=0).unidades constraint pk_idprodbod primary key (idprodbod). constraint pk_idcliente primary key (idcliente) ) create table venta ( idventa integer not null identity.precio de venta unidades integer not null. precioc decimal(8. unidades integer not null.constraint fk_idproveedor foreign key (idproveedor) references proveedor(idproveedor). constraint ck_unidades_bodega check (unidades >=0) ) create table cliente ( idcliente char(8) not null. constraint u_prodcat unique (idproducto.precio de costo preciov decimal(8. constraint ck_precio_catalogo check (precio>=0). fecha datetime not null. idprodbod integer not null. constraint fk_idprodbod foreign key (idprodbod) references bodega(idprodbod). nombre char(60) not null. idprodcat char(16) not null. constraint fk_idventa foreign key (idventa) references venta(idventa). -.

'prov0001'.nuestros proveedores insert into proveedor values ('prov0001'.'prod0001'. 9 .25) insert into catalogo VALUES('prod0003'+'prov0003'.insertando los clientes insert into cliente values ('clie0001'. 'producto d') -. 'producto a') insert into producto values ('prod0002'.insertando que productos distribuye que proveedor y el costo insert into catalogo VALUES('prod0001'+'prov0001'.'prov0001'.3. 'producto c') insert into producto values ('prod0004'.'prov0002'.'proveedor 2') insert into proveedor values ('prov0003'.15.'prov0003'.'proveedor 3') -.3.'prod0002'. dicho código se almacenará en el campo llamado 'idprodcat': -.85) insert into catalogo VALUES('prod0004'+'prov0003'.15) insert into catalogo VALUES('prod0002'+'prov0002'.10) insert into catalogo VALUES('prod0003'+'prov0002'.'prov0002'.'cliente 3') En la tabla de catálogo.'prov0003'.'prod0001'.00) insert into catalogo VALUES('prod0001'+'prov0003'.'cliente 1') insert into cliente values ('clie0002'.3.'proveedor 1') insert into proveedor values ('prov0002'.'prod0001'.'prov0003'.'prod0003'.'prod0002'.14.'prod0004'.00) GUÍA 2 Pág.'cliente 2') insert into cliente values ('clie0003'.-.6. 'producto b') insert into producto values ('prod0003'.productos que ofrecen los proveedores insert into producto values ('prod0001'.50) insert into catalogo VALUES('prod0002'+'prov0001'.'prov0002'.90) insert into catalogo VALUES('prod0004'+'prov0001'.'prod0003'.5.'prod0004'.'prov0001'.2.5. se generará un código para cada producto distribuido por cada proveedor.25) insert into catalogo VALUES('prod0001'+'prov0002'.

@ganancia de tipo decimal y @unidades de tipo entero(int). GUÍA 2 Pág.2). No confundir una variable local con un parámetro de entrada o de salida.Para insertar datos en la bodega. se creara un procedimiento almacenado que toma 5 parámetros de entrada los cuales son: @fecha de tipo datetime. c) La línea if @@rowcount = 0 indica que si el ultimo query realizado no devolvió ningún registro (@@rowcount=0) entonces se hace un salto incondicional a la etiqueta error.@producto de tipo char.@fecha.@precio. @ganancia decimal(4. @producto char(8).@precio+(@precio *@ganancia). Por ejemplo: SELECT @X = 10 ( aquí se le asigna a la variable X el valor de 10 ).2) select @idprodcat = idprodcat from catalogo where idproducto=@producto and idproveedor=@proveedor if @@rowcount=0 goto error select @precio = precio from catalogo where idprodcat = @idprodcat insert into bodega values (@idprodcat. En este caso el query retorna el campo precio de dicha tabla). 10 . b) Para asignarle un valor a una variable se utiliza la sentencia SELECT seguido de la consulta o valor que será almacenado en dicha variable.procedimiento almacenado que inserta productos en bodega create procedure sp_producto_bodega @fecha datetime. @unidades int as declare @idprodcat char(16) declare @precio decimal(8. @proveedor. SELECT @precio = precio from catalogo where idprodcat = @idprodcat (aquí se le esta asignando a la variable precio el dato que retorna la consulta hecha a la tabla catalogo. @proveedor char(8).@unidades) return(0) error: print 'No existe un producto en el catalogo' return(1) GO Algunas características del procedimiento almacenado creado anteriormente son: a) La línea declare @idprodcat char(16) esta declarando una variable local utilizada dentro del SP (Store Procedure). Ejecute el siguiente query para crear el procedimiento almacenado “producto_bodega”: -.

si hay existencia en bodega se permitirá la acción y se actualizarán las existencias en la tabla bodega para que exista consistencia entre los datos (si vendo productos.'prod0002'. El procedimiento almacenado seria el siguiente: create proc sp_actualizar_bodega @idprodbod int.0. 11 .'prov0001'.'prov0001'.'prod0001'.@unidades where idprodbod = @idprodbod commit tran goto fin errores: rollback tran --se elimina la transaccion fin: print 'Bodega actualizada' Por ultimo crearemos un procedimiento almacenado más sofisticado.10 exec sp_producto_bodega '01/01/2000'.0. primero se debe verificar que haya existencia de dicho producto en nuestra bodega.'prov0001'.0.0.'prod0004'.'prod0002'.2.'prov0002'.5 exec sp_producto_bodega '07/01/2000'.2.0.'prod0001'.2. exec sp_producto_bodega '01/01/2000'.'prov0003'. los parámetros a pasar deben ser: el id de la venta. el idprodcat (es decir el codigo del GUÍA 2 Pág.0.2.5 exec sp_producto_bodega '28/01/2000'.15 Ahora procederemos a realizar un procedimiento almacenado que hará referencia a la tabla detalleventa de tal forma que si insertamos la venta de un producto.'prod0003'.d) Si hubo error la sentencia print muestra el mensaje 'No existe un producto en el catalogo'.haciendo las compras a los proveedores en los meses de enero y febrero -.'prod0001'. que permita agregar fácilmente las unidades de un producto a nuestra tabla detalleventa.'prov0003'.15 exec sp_producto_bodega '01/02/2000'.0. de lo contrario se insertan los datos.2.20 exec sp_producto_bodega '01/02/2000'.15 exec sp_producto_bodega '01/01/2000'. disminuye mi bodega). @unidades int as declare @existencia int select @existencia = unidades from bodega where idprodbod = @idprodbod begin tran if (@existencia<@unidades) goto errores update bodega set unidades = unidades . Utilice el procedimiento almacenado creado anteriormente para insertar los siguientes datos: -.del 2000 y ganando un 20% sobre el costo.2.'prov0002'.2.

ya que se deben explorar todas las compras realizadas de ese producto ordenadas por fechas y decrementar las entradas (compras) más antiguas.producto distribuido por un proveedor determinado) y las unidades vendidas. 12 .unidades from bodega where idprodcat=@idprodcat order by fecha asc --comienza una transaccion begin tran open ctmp --Ejecutando el primer fetch y almacenando los valores en variables --Las variables estan en el mismo orden de las columnas de la --sentencia SELECT del cursor fetch next from ctmp into @idprodbod. El procedimiento almacenado queda de la siguiente forma: create procedure sp_producto_detalleventa @idventa int.@unidadestmp end else begin GUÍA 2 Pág. @idprodcat char(16). El procedimiento almacenado necesita crear un cursor. se venderán los productos comprados en las fechas más antiguas.@unidadestmp) --actualizando bodega llamando al SP EXEC sp_actualizar_bodega @idprodbod. y como la política es vender el producto más antiguo.@unidadestmp while (@unidades>0 and @@fetch_status=0) begin if @unidadestmp <= @unidades begin select @unidades=@unidades-@unidadestmp insert into detalleventa values(@idventa. Nuestro procedimiento almacenado consultará nuestra bodega para revisar las compras que se han efectuado de ese producto. Además dicho procedimiento llamara al SP actualizar_bodega.@idprodbod. @unidades int as declare @idprodbod char(8) declare @existencia int declare @unidadestmp int select @existencia=sum(unidades) from bodega where idprodcat=@idprodcat if @existencia < @unidades goto errores declare ctmp cursor for select idprodbod.

visualizando como cambiaron nuestros registros en bodega select * from bodega where idprodcat='prod0001prov0001' GUÍA 2 Pág. una realizada el 1 de enero del 2000 por 5 unidades y otra realizada el 7 de enero del 2000 por 15 por lo que se tienen 20 unidades en total.'clie0001') Ahora se ingresaran datos en la tabla detalleventa utilizando el procedimiento almacenado sp_ producto_detalleventa. 4 GO del producto Ahora ejecute este query para ver el estado de la tabla bodega: -.@unidades select @unidades=0 end fetch next from ctmp into @idprodbod. Primero visualicemos cuantas compras se han realizado „prod0001prov0001‟ (producto 1 distribuido por el proveedor 1) select * from bodega where idprodcat='prod0001prov0001' Observe que existen dos compras.obteniendo el valor del codigo idventa en una variable declare @idventa int select @idventa=idventa from venta where idcliente='clie0001' --suponiendo que el cliente 01 compra 4 unidades EXEC sp_producto_detalleventa @idventa.@idprodbod.insert into detalleventa values(@idventa. 13 . Ejecute los siguientes querys como un solo batch (ambos querys de una sola vez): -.@unidadestmp end close ctmp deallocate ctmp --la transaccion finaliza commit tran return 0 errores: return 1 Para comprobar la ejecución de los procedimientos almacenados anteriores. 'prod0001prov0001'. Registrando la venta para el cliente 1: insert into venta values ('28/03/2001'.@unidades) --actualizando bodega llamando al SP EXEC sp_actualizar_bodega @idprodbod. se harán unas pruebas registrando una venta para el cliente con código „clie0001‟.

'Abarca'.se registra primero la venta del cliente 02 insert into venta values ('28/03/2001'.'no') values('3'.'no') Como puede ver se insertaron registros y el campo de nombre completo no se ingreso correctamente. Ejemplo Cursores A la misma base de datos insertar la siguiente tabla create table nombrecito( cod int. El select debe contener sólo los campos a utilizar.el cliente 02 compra 7 unidades Exec sp_producto_detalleventa @idventa.apellido from nombrecito GUÍA 2 Pág.'Jose'. mientras que del segundo se decremento en 6. declare MICURSOR cursor for select cod. nombre varchar(25).'Lissette'. 14 . nombre.'Castro'. apellido varchar(25). para ello haremos uso de cursores -.Observe como se disminuyo en 4 el primer lote de compras.'Carlos'. por lo que tendremos que actualizar registro por registro. Suponga ahora que el cliente 02 realiza una compra por 7 unidades del mismo producto: -.'Juan'.'Jimenez'.declaramos un cursor llamado "MICURSOR".'Elias'. del primer lote de compras ya no hay existencia.'clie0002') declare @idventa int select @idventa=idventa from venta where idcliente='clie0002' -. nombrecompleto varchar(50)) insert insert insert insert into into into into nombrecito nombrecito nombrecito nombrecito values('1'.'no') values('2'.declaramos las variables declare @cod as int declare @nombre as varchar(25) declare @apellido as varchar(25) -. 'prod0001prov0001'. 7 Observe como se han modificado los registros en la tabla bodega : select * from bodega where idprodcat='prod0001prov0001' Se puede observar.'no') values('4'.

cerramos el cursor close MICURSOR deallocate MICURSOR V. @nombre.Avanzamos otro registro fetch next from MICURSOR into @cod.open MICURSOR --Avanzamos un registro y cargamos en las variables los valores encontrados en el primer registro fetch next from MICURSOR into @cod. INVESTIGACIÓN Y EJERCICIOS COMPLEMENTARIOS Investigue que son los desencadenadores Cual es la diferencia entre un desencadenador DDL y DML Implemente un trigger en la tabla producto el cual se debe activar cuando halla una actualizacion de datos en dicha tabla GUÍA 2 Pág. 15 . @apellido while @@fetch_status = 0 begin update nombrecito set nombrecompleto= @nombre+' '+@apellido where cod=@cod -. @nombre. @apellido end -.

You're Reading a Free Preview

Download
scribd
/*********** DO NOT ALTER ANYTHING BELOW THIS LINE ! ************/ var s_code=s.t();if(s_code)document.write(s_code)//-->