Guia 2 SQL Server

download Guia 2 SQL Server

of 15

Transcript of Guia 2 SQL Server

Tema: Procedimientos almacenados y cursores.

Facultad : Ingeniera Escuela : Computacin Asignatura: SQL SERVER

GUA 2 Pg.

1

I. OBJETIVOS Utilizar procedimientos almacenados Conocer el uso de los cursores Realizar operaciones utilizando transacciones

II. INTRODUCCIN

Programacin con Transact-SQL

Transact-SQL no es realmente un lenguaje de programacin similar a las herramientas de tercera y cuarta generacin sin embargo permite utilizar SQL para realizar tareas complejas que requieren saltos, bucles, decisiones. Transact-SQL se utiliza a menudo en la creacin de procedimientos almacenados y triggers de tal forma que las aplicaciones clientes que se conectan a SQL Server solo se preocupan por la presentacin de los datos para el usuario final, mientras que la lgica de los procesos se maneja en el servidor. Variables: Las variables locales se identifican como aquellos objetos que comienzan con el carcter arroba '@' una vez; las variables globales se identifican como los objetos que tienen 2 arrobas al inicio '@@', como ejemplo de variables globales tenemos: @@rowcount, @@error. Las variables locales se declaran al inicio de un proceso por lotes o un procedimiento almacenado, la forma de asignarle valores a una variable es con la instruccin SELECT. El control de flujo en Transact-SQL Construccin IF..ELSE GOTO etiqueta WAITFOR Descripcin Define una decisin. Define un salto incondicional Establece un tiempo para la ejecucin de una instruccin. El tiempo puede ser un intervalo de retardo o un instante especificado de ejecucin (una hora concreta del da) Bucle bsico de SQL Acompaa al bucle WHILE y le indica finalizarlo inmediatamente. Acompaa al bucle WHILE y le indica continuar con la siguiente iteracin. Salida incondicional del procedimiento oGUA 2 Pg.

WHILE BREAK CONTINUE RETURN [n]

2

BEGIN..END

CASE

proceso por lotes, se puede definir un nmero entero como estado devuelto y puede asignarse a cualquier variable. Utilizado en conjunto con IF..ELSE o WHILE para agrupar un conjunto de instrucciones. Implementada en la instruccin SELECT y UPDATE y permite realizar consultas y actualizaciones condicionales.

PRINT Es una instruccin para imprimir un dato en la pantalla, la sintaxis es: PRINT "cadena" ; cadena puede ser tambin una variable de tipo varchar. Por ejemplo: PRINT Hola a todos RAISERROR Es similar a PRINT, pero permite especificar un nmero de error y la severidad del mensaje. RAISERROR tambin permite que los errores se registren en el servicio de sucesos de Windows NT haciendo posible leerlos a travs del visor de sucesos de Windows NT. La sintaxis es: RAISERROR({id_mensaje | cadena_mensaje}, severidad, estado [, argumento1 [,argumento2]]) WITH LOG. Despus de llamar a RAISERROR, la variable global @@ERROR tendr el valor de id_mensaje, si no se pasa ningn id_mensaje, asumir 5000. Procedimientos almacenados. Dos de las cuestiones ms importantes para el usuario de bases de datos son la velocidad y la eficiencia. Por ello surge una pregunta: Cmo puedo proporcionar a los usuarios la velocidad y eficiencia que necesitan y merecen? Esa herramienta diseada principalmente para optimizar la obtencin de datos, es el procedimiento almacenado. Un procedimiento almacenado es una consulta que se almacena en una base de datos en SQL Server en lugar de almacenarse en el cdigo cliente (normalmente C# o Java) en el equipo cliente.

Creacin de procedimientos almacenados (Store Procedures)

La instruccin general para crear procedimientos almacenados es la siguiente: CREATE PROC nombre_proc parametros

GUA 2 Pg.

3

AS INSTRUCCION SQL Es necesario aclarar, que un procedimiento almacenado puede recibir parmetros de entrada y devolver parmetros de salida. Ejemplo 1 Instruccin SQLUSE AdventureWorks Select name, Color, ListPrice, SellStartDate FROM Production.Product WHERE SellStartDate > '1/1/2003' ORDER BY SellStartDate, Name

Procedimiento con instruccin anteriorCREATE PROCEDURE Production.ShowProduct AS Select name, Color, ListPrice, SellStartDate FROM Production.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 cdigo siguiente. USE AdventureWorks EXEC Production.ShowProduct Nota: los procedimientos almacenados los puede encontrar en la base de datos donde los trabaja, en la opcin programacin. Ejemplo2: --Obteniendo Ganancia sobre las ventas CREATE PROC Ganancia_de_Venta @id_Venta int, -- parametro de entrada @id_Prod_bodega int, -- parametro de entrada @ganancia decimal (8,2) OUTPUT -- 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 GOGUA 2 Pg.

4

Reglas de procedimientos almacenados Entre las reglas para la programacin de procedimientos almacenados, cabe citar las siguientes: La propia definicin CREATE PROCEDURE puede incluir cualquier nmero y tipo de instrucciones SQL, excepto las siguientes instrucciones CREATE, 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. Puede hacer referencia a un objeto creado en el mismo procedimiento almacenado, siempre que se cree antes de que se haga referencia al objeto. Puede hacer referencia a tablas temporales dentro de un procedimiento almacenado. Si ejecuta un procedimiento almacenado que llama a otro procedimiento almacenado, el procedimiento al que se llama puede tener acceso a todos los objetos creados por el primer procedimiento, incluidas las tablas temporales. El nmero mximo de parmetros en un procedimiento almacenado es de 1,024. El nmero mximo de variables locales en un procedimiento almacenado est limitado nicamente por la memoria disponible. 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. Los procedimientos almacenados del sistema se crean y se almacenan en la base de datos master, con el prefijo sp_ (stored procedure). Estos procedimientos se pueden ejecutar desde cualquier base de datos. Por ejemplo: sp_help, sp_heldb, sp_droplogin, etc. Cursores Una base de datos relaciona como SQL Server est orientada a conjuntos de manera natural, por ejemplo una instruccin SELECT regresa un conjunto de datos; sin embargo muchas veces es necesario utilizar no el enfoque de conjunto de datos sino de registros para realizar ciertas operaciones no complejas, es donde se implementan los cursores. Un cursor es un conjunto de resultados donde existe la posibilidad de desplazarse registro por registro en cualquier direccin.GUA 2 Pg.

5

Trabajar con cursores implica algunos pasos bsicos como son el declararlos, abrirlos, capturar filas en el cursor, opcionalmente se puede modificar o eliminar registros, luego se debe cerrar el cursor y por ultimo retirarlo de la memoria. Cuando se crean cursores, se debe considerar lo siguiente:-

-

-

Para declarar un cursor se utiliza la instruccin DECLARE. Para abrir el cursor se utiliza la instruccin OPEN Para capturar filas de un cursor se utiliza la instruccin FETCH, es necesario declarar variables e indicarle a FETCH cuales son las variables., existe una variable global llamada @@FETCH_STATUS que indica el estado de la ltima instruccin FETCH, as si @@ FETCH_STATUS = 0 la captura fue un xito, 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, se utiliza la instruccin UPDATE / DELETE tabla WHERE CURRENT OF nombre_cursor. Para cerrar el cursor, se utiliza la instruccin: CLOSE. Para liberar la memoria, se utiliza la instruccin DEALLOCATE.

III. MATERIAL Y EQUIPO A UTILIZAR Gua de Laboratorio N 2 de SQL Server Computadora con SQL SERVER 2005 Disquete o memoria USB IV. PROCEDIMIENTO En esta prctica utilizaremos los procedimientos almacenados, cursores y transacciones utilizando la base de datos de SQL Server 2005, para ello se plantea la siguiente base de datos: Definicin. Esta base de datos se desea para un almacn que tiene varios productos a la venta, los cuales adquiere de varios proveedores. Un producto puede ser distribuido por varios proveedores y un proveedor distribuye varios productos, como es una relacin de muchos a muchos se tiene una tercera tabla llamada "catalogo" donde se indica el detalle del producto. Lo interesante es que el almacn adquiere productos a cierto precio y los almacena en bodega, y a medida que las existencias del producto van disminuyendo, vuelve a adquirir nuevos productos, sin embargo el costo del producto comprado por el almacn puede variar y el almacn registra el precio de costo y de venta de los productosGUA 2 Pg.

6

adquiridos en una compra y maneja la poltica de vender primero los productos ms antiguos.

Para poder crear la base de datos anterior, deber crear una base de datos con el nombre almacen_carnet, y ejecute los scripts para generar las tablas que se listan a continuacin:-- creacion de las tablas create table proveedor ( idproveedor char(8) not null, nombre char(60) not null, constraint pk_idproveedor primary key (idproveedor) ) create table producto ( idproducto char(8) not null, nombre char(60) not null, constraint pk_idproducto primary key (idproducto) ) create table catalogo ( idprodcat char(16) not null, idproducto char(8) not null, idproveedor char(8) not null, precio decimal(8,2) not null, constraint pk_idprodcat primary key clustered (idprodcat), GUA 2 Pg.

7

constraint fk_idproveedor foreign key (idproveedor) references proveedor(idproveedor), constraint fk_idproducto foreign key (idproducto) references producto(idproducto), constraint u_prodcat unique (idproducto,idproveedor), constraint ck_precio_catalogo check (precio>=0), constraint ck_idprodcat_catalogo check (idprodcat=idproducto+idproveedor) ) create table bodega ( idprodbod integer not null identity, idprodcat char(16) not null, fecha datetime not null, precioc decimal(8,2) not null, -- precio de costo preciov decimal(8,2) not null, -- precio de venta unidades integer not null, -- unidades constraint pk_idprodbod primary key (idprodbod), constraint fk_idprodcat foreign key (idprodcat) references catalogo(idprodcat), constraint ck_precios_bodega check (precioc >=0 and preciov >=0), constraint ck_unidades_bodega check (unidades >=0) ) create table cliente ( idcliente char(8) not null, nombre char(60) not null, constraint pk_idcliente primary key (idcliente) )

create table venta ( idventa integer not null identity, fecha datetime not null, idcliente char(8) not null, constraint pk_idventa primary key (idventa), constraint fk_idcliente foreign key (idcliente) references cliente(idcliente) ) create table detalleventa ( idventa integer not null, idprodbod integer not null, unidades integer not null, constraint fk_idprodbod foreign key (idprodbod) references bodega(idprodbod), constraint fk_idventa foreign key (idventa) references venta(idventa), constraint ck_unidades_detalleventa check (unidades>0) )

Ejecute las siguientes instrucciones SQL para introducir datos a las tablas de trabajo:

GUA 2 Pg.

8

-- productos que ofrecen los proveedores insert into producto values ('prod0001', 'producto a') insert into producto values ('prod0002', 'producto b') insert into producto values ('prod0003', 'producto c') insert into producto values ('prod0004', 'producto d') -- nuestros proveedores insert into proveedor values ('prov0001','proveedor 1') insert into proveedor values ('prov0002','proveedor 2') insert into proveedor values ('prov0003','proveedor 3') -- insertando los clientes insert into cliente values ('clie0001','cliente 1') insert into cliente values ('clie0002','cliente 2') insert into cliente values ('clie0003','cliente 3')

En la tabla de catlogo, se generar un cdigo para cada producto distribuido por cada proveedor, dicho cdigo se almacenar en el campo llamado 'idprodcat':-- insertando que productos distribuye que proveedor y el costo insert into catalogo VALUES('prod0001'+'prov0001','prod0001','prov0001',5.25) insert into catalogo VALUES('prod0001'+'prov0002','prod0001','prov0002',6.00) insert into catalogo VALUES('prod0001'+'prov0003','prod0001','prov0003',5.50) insert into catalogo VALUES('prod0002'+'prov0001','prod0002','prov0001',3.15) insert into catalogo VALUES('prod0002'+'prov0002','prod0002','prov0002',3.10) insert into catalogo VALUES('prod0003'+'prov0002','prod0003','prov0002',15.25) insert into catalogo VALUES('prod0003'+'prov0003','prod0003','prov0003',14.90) insert into catalogo VALUES('prod0004'+'prov0001','prod0004','prov0001',3.85) insert into catalogo VALUES('prod0004'+'prov0003','prod0004','prov0003',2.00)

GUA 2 Pg.

9

Para insertar datos en la bodega, se creara un procedimiento almacenado que toma 5 parmetros de entrada los cuales son: @fecha de tipo datetime, @proveedor,@producto de tipo char, @ganancia de tipo decimal y @unidades de tipo entero(int). Ejecute el siguiente query para crear el procedimiento almacenado producto_bodega:-- procedimiento almacenado que inserta productos en bodega create procedure sp_producto_bodega @fecha datetime, @proveedor char(8), @producto char(8), @ganancia decimal(4,2), @unidades int as declare @idprodcat char(16) declare @precio decimal(8,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,@fecha,@precio,@precio+(@precio *@ganancia),@unidades) return(0) error: print 'No existe un producto en el catalogo' return(1) GO

Algunas caractersticas del procedimiento almacenado creado anteriormente son: a) La lnea declare @idprodcat char(16) esta declarando una variable local utilizada dentro del SP (Store Procedure). No confundir una variable local con un parmetro de entrada o de salida. 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. Por ejemplo: SELECT @X = 10 ( aqu se le asigna a la variable X el valor de 10 ). 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. En este caso el query retorna el campo precio de dicha tabla).

c) La lnea if @@rowcount = 0 indica que si el ultimo query realizado no devolvi ningn registro (@@rowcount=0) entonces se hace un salto incondicional a la etiqueta error.GUA 2 Pg.

10

d) Si hubo error la sentencia print muestra el mensaje 'No existe un producto en el catalogo', de lo contrario se insertan los datos. Utilice el procedimiento almacenado creado anteriormente para insertar los siguientes datos:-- haciendo las compras a los proveedores en los meses de enero y febrero -- del 2000 y ganando un 20% sobre el costo. exec sp_producto_bodega '01/01/2000','prov0001','prod0001',0.2,5 exec sp_producto_bodega '28/01/2000','prov0002','prod0003',0.2,15 exec sp_producto_bodega '01/01/2000','prov0002','prod0002',0.2,10 exec sp_producto_bodega '01/01/2000','prov0003','prod0004',0.2,20 exec sp_producto_bodega '01/02/2000','prov0003','prod0001',0.2,15 exec sp_producto_bodega '01/02/2000','prov0001','prod0002',0.2,5 exec sp_producto_bodega '07/01/2000','prov0001','prod0001',0.2,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, primero se debe verificar que haya existencia de dicho producto en nuestra bodega; si hay existencia en bodega se permitir la accin y se actualizarn las existencias en la tabla bodega para que exista consistencia entre los datos (si vendo productos, disminuye mi bodega). El procedimiento almacenado seria el siguiente:create proc sp_actualizar_bodega @idprodbod int, @unidades int as declare @existencia int select @existencia = unidades from bodega where idprodbod = @idprodbod begin tran if (@existencia0 and @@fetch_status=0) begin if @unidadestmp