Tema: Procedimientos almacenados y cursores. Facultad : Ingeniería Escuela : Computación Asignatura: SQL SERVER. GUÍA 2 Pág. 1



Documentos relacionados
Tema: PROCEDIMIENTOS ALMACENADOS.

UNIVERSIDAD DEL ISTMO CAMPUS IXTEPEC LIC. INFORMATICA GRUPO 508 PROCEDIMIENTOS ALMACENADOS EN SQL SERVER 2000

MANUALITO MS-SQL SERVER

Formato para prácticas de laboratorio

Administradores de Bases de Datos Studio.NET 2005 Y SQL Server Barrios

CURSORES EN SQL SERVER

El lenguaje de manipulación de datos (DML) es una parte fundamental de SQL.

Bases de Datos SQL 1 SQL. Jorge Pérez R. Universidad de Talca, II Semestre 2006

PL/SQL. Con PL/SQL vamos a poder programar las unidades de programa de la base de datos Oracle:

6. PROGRAMACIÓN CON TRANSACT-SQL

El usuario puede utilizar esta tabla derivada como una tabla más, en sus consultas.

Programación SQL. Lucio Salgado Diciembre 2008

Tema: Disparadores Parte I.

PROCEDIMIENTOS ALMACENADOS. CREATE PROCEDURE nombreprocedimiento tipodato [=valordefecto]][,...]

GUIA DE LABORATORIO N 9 B. (000Webhost Php- Para desarrollar en casa)

APUNTES: APLICACIONES WEB BASADAS EN PHP Y MYSQL Página 1 de 5

GALA CONCEPTO COMMIT, ROOLBACK SAVEPOINTS (SAVE TRANSACTION) No Consultas. Definiciones Transacciones ( L33 )

SQL (Structured Query Language)

Procedimientos, Funciones, Trigger y Cursores en ORACLE

BASES DE DATOS AVANZADAS Transacciones en MYSQL

ADMINISTRACIÓN DE BASE DE DATOS

CONSULTAS CON SQL. 3. Hacer clic sobre el botón Nuevo de la ventana de la base de datos. Aparecerá el siguiente cuadro de diálogo.

Microsoft SQL Server 2005

T12 Vistas y tablas temporales

UNIVERSIDAD DON BOSCO FACULTAD DE ESTUDIOS TECNOLOGICOS ESCUELA DE COMPUTACION

UNIVERSIDAD NACIONAL DE SAN AGUSTÍN FACULTAD DE PRODUCCIÓN Y SERVICIOS ESCUELA PROFESIONAL DE INGENIERÍA DE SISTEMAS LABORATORIO DE BASES DE DATOS 1

Índice. iii. Objetivos... 24

Oracle básico (IV): Programación en PL/SQL

Curso Online de Microsoft

Bases de Datos Relacionales

8283: Administración y programación en Microsoft SQL Server 2012

CURSO DE SQL SERVER 2005

Es un lenguaje de consulta estructurado establecido claramente como lenguaje de alto nivel estándar para sistemas de base de datos relacionales.

: COMPUTACIÓN E INFORMATICA : Ingeniería de Software Ingeniería de Redes y Comunicaciones : Administración de Bases de Datos I : T-INF127

Formato para prácticas de laboratorio

Trabajos de Ampliación. Bases de datos NoSQL.

INTRODUCCIÓN INTRODUCCIÓN INTRODUCCIÓN INTRODUCCIÓN INSTRUCCIONES DE DEFINICIÓN DE TABLAS E ÍNDICES INSTRUCCIONES DE DEFINICIÓN DE TABLAS E ÍNDICES

Acronis License Server. Guía del usuario

LABORATORIO 10. ADMINISTRACIÓN DE COPIAS DE SEGURIDAD EN SQL SERVER

Repaso. Laboratorio Informix. Stored Procedures. Ejemplo. Creación de stored procedures. Sql en un Procedimiento

1. DML. Las subconsultas

Sistemas de Datos Curso: Ernesto Chinkes. Subconsultas Stored Procedures - Triggers

BASE DE DATOS QUÉ ES UNA BASE DE DATOS?

SENTENCIAS Y CONSULTAS EN SQL SERVER

m047a Curso Programando una Base de Datos SQL Server 2008, 36 h Creación B.D. y Constraints

Unidad III: Lenguaje de manipulación de datos (DML) 3.1 Inserción, eliminación y modificación de registros

Base de datos Procedimientos Almacenados y Funciones

Base de Datos Práctica 1.

Laboratorio Informix. Stored Procedures Triggers

Curso Oficial Microsoft: LENGUAJE DE CONSULTA DE SQL SERVER. Duración : 35 Hrs.

EL ENTORNO DE TRABAJO SQL ORACLE

Curso de PHP con MySQL Gratis

TRANSACT-SQL, DISEÑO Y PROGRAMACIÓN DE BASES DE DATOS EN SQL SERVER 2008

m047a Curso Programando una Base de Datos SQL Server 2008, 36 h

Tema: CREACIÓN DE TABLAS DE RDBMS (RELATIONAL DATA BASE MANAGEMENT SYSTEM).

LENGUAJE ESTRUCTURADO DE CONSULTAS SQL (2)

4- Uso de sentencias para el envió y extracción de datos

Plan de mantenimiento. NetSupport ServiceDesk

Tema: CREACIÓN DE TABLAS DE RDBMS (RELATIONAL DATA BASE MANAGEMENT SYSTEM).

SQL Server SQL, Transact SQL Diseño y creación de una base de datos

Formato para prácticas de laboratorio

CONSULTAS DE RESUMEN SQL SERVER Manual de Referencia para usuarios. Salomón Ccance CCANCE WEBSITE

Tablas y Campos Nuevos

- Bases de Datos - - Diseño Físico - Luis D. García

Consultas con combinaciones

Introducción a PostgreSQL con PHP

Base de datos en Excel

Bases de Datos Relacionales

Implementación de funciones definidas por el usuario

Tema: CREACIÓN DE CONSULTAS E INFORMES EN UNA BASE DE DATOS CON MICROSOFT ACCESS 2013.

SQL dinámico en Transact SQL

5- Uso de sentencias avanzadas

Base de datos relacional

Comisión Nacional de Bancos y Seguros

A- CREAR COPIA FÍSICA Y HEREDAR REGISTRO DE CONFIGURACIÓN

Maestría en Bioinformática. Bases de Datos y Sistemas de Información. Diseño Lógico. Ing. Alfonso Vicente, PMP alfonso.vicente@logos.com.

Bases de Datos / Elementos de Bases de Datos Que es un Stored Procedure? Stored Procedures: Ventajas

Uso de las herramientas de consulta de Transact-SQL

LENGUAJE DE CONSULTA ESTRUCTURADO - SQL CONTENIDO

ST31_Querying Microsoft SQL Server

SQL Server SQL, Transact SQL Diseño y creación de una base de datos (con ejercicios prácticos corregidos)

Que es PHP? Que se puede hacer con PHP? Sintaxis del lenguaje. Variables. Operadores básicos. Condicionales. Ciclos.

El Lenguaje PL/SQL. Un lenguaje de propósito general orientado a la inclusión de sentencias SQL. Estructura del código PL/SQL.

Una variable de clase escalar tiene un nivel de indirección igual a 1. Por ejemplo, las variables i, b y x definidas como se muestra a continuación.

O C T U B R E SOPORTE CLIENTE. Manual de Usuario Versión 1. VERSIÓN 1 P á g i n a 1

Oracle 12c DISEÑO Y PROGRAMACIÓN

DESCRIPCIÓN ESPECÍFICA

CONSULTAS BASICAS EN SQL SERVER

CURSO TRANSACT SQL MANUAL TÉCNICO CURSO TRANSACT SQL MANUAL TÉCNICO 1

Enlaces relacionados:

El lenguaje SQL es un lenguaje estándar para el acceso y

LABORATORIO 10. COPIAS DE SEGURIDAD, RESTAURACIÓN Y RECUPERACIÓN DE UNA BD

A continuación se describen cuáles son los elementos principales de las tablas, cómo crear una y cómo modificarla.

ESCUELA DE CIENCIAS BASICAS TECNOLOGIA E INGENIERIA Programación de sitios web Act 11: Reconocimiento de la unidad 3

MS_20461 Querying Microsoft SQL Server

Programación de Consultas SQL ADO.Net LDP / DUOC-AV

COMANDOS DE SQL, OPERADORES, CLAUSULAS Y CONSULTAS SIMPLES DE SELECCIÓN

Objetos de la Base de Datos

BASE DE DATOS - CURSO 02/03 PRÁCTICA 2: SQL: Lenguaje de definición de datos (DDL)

GUIA COMPLEMENTARIA PARA EL USUARIO DE AUTOAUDIT. Versión N 02 Fecha: 2011-Febrero Apartado: Archivos Anexos ARCHIVOS ANEXOS

Transcripción:

Tema: Procedimientos almacenados y cursores. Facultad : Ingeniería Escuela : Computación Asignatura: SQL SERVER GUÍA 2 Pág. 1

I. OBJETIVOS Utilizar procedimientos almacenados Conocer el uso de los cursores Realizar operaciones utilizando transacciones II. 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, bucles, decisiones. 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, 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; 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 instrucción SELECT. El control de flujo en Transact-SQL Construcción IF..ELSE GOTO etiqueta WAITFOR WHILE BREAK CONTINUE RETURN [n] Descripción Define una decisión. Define un salto incondicional Establece un tiempo para la ejecución de una instrucción. 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. Acompaña al bucle WHILE y le indica continuar con la siguiente iteración. Salida incondicional del procedimiento o GUÍA 2 Pág. 2

BEGIN..END CASE proceso por lotes, se puede definir un número 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 instrucción SELECT y UPDATE y permite realizar consultas y actualizaciones condicionales. PRINT Es una instrucción para imprimir un dato en la pantalla, la sintaxis es: PRINT "cadena" ; cadena puede ser también una variable de tipo varchar. Por ejemplo: PRINT Hola a todos RAISERROR Es similar a PRINT, pero permite especificar un número de error y la severidad del mensaje. 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. La sintaxis es: RAISERROR({id_mensaje cadena_mensaje}, severidad, estado [, argumento1 [,argumento2]]) WITH LOG. Después de llamar a RAISERROR, la variable global @@ERROR tendrá el valor de id_mensaje, si no se pasa ningún id_mensaje, asumirá 5000. Procedimientos almacenados. Dos de las cuestiones más importantes para el usuario de bases de datos son la velocidad y la eficiencia. 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, 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 código cliente (normalmente C# o Java) en el equipo cliente. 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. 3

AS INSTRUCCION SQL Es necesario aclarar, que un procedimiento almacenado puede recibir parámetros de entrada y devolver parámetros de salida. Ejemplo 1 Instrucción SQL USE AdventureWorks Select name, Color, ListPrice, SellStartDate FROM Production.Product WHERE SellStartDate > '1/1/2003' ORDER BY SellStartDate, Name Procedimiento con instrucción anterior GO CREATE PROCEDURE Production.ShowProduct AS Select name, Color, ListPrice, SellStartDate FROM Production.Product WHERE SellStartDate > '1/1/2003' ORDER BY SellStartDate, Name Para probar el nuevo procedimiento, abra una nueva consulta de SQL Server y escriba y ejecute el código siguiente. USE AdventureWorks EXEC Production.ShowProduct Nota: los procedimientos almacenados los puede encontrar en la base de datos donde los trabaja, en la opción programación. 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 GO GUÍA 2 Pág. 4

Reglas de procedimientos almacenados Entre las reglas para la programación de procedimientos almacenados, cabe citar las siguientes: La propia definición CREATE PROCEDURE puede incluir cualquier número 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 número máximo de parámetros en un procedimiento almacenado es de 1,024. El número máximo 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 instrucción 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 dirección. GUÍA 2 Pág. 5

Trabajar con cursores implica algunos pasos básicos 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 instrucción DECLARE. - Para abrir el cursor se utiliza la instrucción OPEN - Para capturar filas de un cursor se utiliza la instrucción 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 instrucción 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 instrucción UPDATE / DELETE tabla WHERE CURRENT OF nombre_cursor. - Para cerrar el cursor, se utiliza la instrucción: CLOSE. - Para liberar la memoria, se utiliza la instrucción DEALLOCATE. III. MATERIAL Y EQUIPO A UTILIZAR Guía de Laboratorio Nº 2 de SQL Server Computadora con SQL SERVER 2005 Disquete o memoria USB IV. PROCEDIMIENTO En esta práctica 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: Definición. Esta base de datos se desea para un almacén 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 relación de muchos a muchos se tiene una tercera tabla llamada "catalogo" donde se indica el detalle del producto. Lo interesante es que el almacén 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 almacén puede variar y el almacén registra el precio de costo y de venta de los productos GUÍA 2 Pág. 6

adquiridos en una compra y maneja la política de vender primero los productos más 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 continuación: -- 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), GUÍA 2 Pág. 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: GUÍA 2 Pág. 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 catálogo, se generará un código para cada producto distribuido por cada proveedor, dicho código 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) GUÍA 2 Pág. 9

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, @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 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). No confundir una variable local con un parámetro 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 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. GUÍA 2 Pág. 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 acción y se actualizarán 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 (@existencia<@unidades) goto errores update bodega set unidades = unidades - @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, que permita agregar fácilmente las unidades de un producto a nuestra tabla detalleventa, los parámetros a pasar deben ser: el id de la venta, el idprodcat (es decir el codigo del GUÍA 2 Pág. 11

producto distribuido por un proveedor determinado) y las unidades vendidas. Además dicho procedimiento llamara al SP actualizar_bodega. Nuestro procedimiento almacenado consultará nuestra bodega para revisar las compras que se han efectuado de ese producto, y como la política es vender el producto más antiguo, se venderán los productos comprados en las fechas más antiguas. El procedimiento almacenado necesita crear un cursor, ya que se deben explorar todas las compras realizadas de ese producto ordenadas por fechas y decrementar las entradas (compras) más antiguas. El procedimiento almacenado queda de la siguiente forma: create procedure sp_producto_detalleventa @idventa int, @idprodcat char(16), @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,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,@unidadestmp while (@unidades>0 and @@fetch_status=0) begin if @unidadestmp <= @unidades begin select @unidades=@unidades-@unidadestmp insert into detalleventa values(@idventa,@idprodbod,@unidadestmp) --actualizando bodega llamando al SP EXEC sp_actualizar_bodega @idprodbod,@unidadestmp end else begin GUÍA 2 Pág. 12

insert into detalleventa values(@idventa,@idprodbod,@unidades) --actualizando bodega llamando al SP EXEC sp_actualizar_bodega @idprodbod,@unidades select @unidades=0 end fetch next from ctmp into @idprodbod,@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, se harán unas pruebas registrando una venta para el cliente con código clie0001. Primero visualicemos cuantas compras se han realizado del producto prod0001prov0001 (producto 1 distribuido por el proveedor 1) select * from bodega where idprodcat='prod0001prov0001' Observe que existen dos compras, 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. Registrando la venta para el cliente 1: insert into venta values ('28/03/2001','clie0001') Ahora se ingresaran datos en la tabla detalleventa utilizando el procedimiento almacenado sp_ producto_detalleventa. Ejecute los siguientes querys como un solo batch (ambos querys de una sola vez): -- 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, 'prod0001prov0001', 4 GO Ahora ejecute este query para ver el estado de la tabla bodega: -- visualizando como cambiaron nuestros registros en bodega select * from bodega where idprodcat='prod0001prov0001' GUÍA 2 Pág. 13

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

open MICURSOR --Avanzamos un registro y cargamos en las variables los valores encontrados en el primer registro fetch next from MICURSOR into @cod, @nombre, @apellido while @@fetch_status = 0 begin update nombrecito set nombrecompleto= @nombre+' '+@apellido where cod=@cod -- Avanzamos otro registro fetch next from MICURSOR into @cod, @nombre, @apellido end -- cerramos el cursor close MICURSOR deallocate MICURSOR V. 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