miércoles, 7 de septiembre de 2022

¿Cómo trasladar valores entre procedimientos almacenados en MySQL?

 

Para esta demostración estamos usando la base de datos de ejemplo de Northwind en Mysql que consiste en un sistema de pedidos, cuenta con las tablas Customers, Orders, OrderDetails, Products, Categories, Suppliers, Employees, entre otras.

En principio queremos crear un procedimiento que llame a otro procedimiento almacenado, así que vamos a crear dos procedimientos el primero solicita como parametro el código del cliente y contendra la instrucción para eliminar el cliente.

El segundo procedimiento también solicita el codigo del cliente y usa una condición para evaluar si el cliente tiene ordenes y si tiene indicara que no se puede eliminar el cliente pero si no tiene invocará al primer procedimiento almacenado, el código SQL debe de ser:

Procedimiento 1:
Delimiter $$
Create procedure Proc_DeleteCustomer (In Codigo varchar(5))
Begin
Delete from Customers where Customerid=Codigo;
End
$$
Delimiter ;

Procedimiento 2:

Delimiter $$
Create procedure Proc_QuitarCliente (In IDcliente varchar(5))
Begin
If (Select Count(*) from Orders where Customerid=IDCliente)>0 then
Select 'No se puede eliminar a este cliente';
else
Call Proc_DeleteCustomer (IDcliente);
end if;
End
$$
Delimiter ;

Ahora en un segundo ejercicio se necesita crear un procedimiento almacenado que inserte un nuevo registro en la tabla OrderDetails, dentro de los campos que se deben de insetar esta el Precio por Unidad al que se vende el producto pero este precio en vez de ingresarlo se debe de buscar del catalogo de productos, que es la tabla productos, a través de un procedimiento almacenado:

En resumen el primer procedimiento debe buscar el precio del producto y luego trasladarselo al segundo procedimiento, esto se puede hacer de dos formas, la primera forma es creando una tabla temporal que usen los dos procedimientos y que sirva para compartir el dato buscado. La segunda forma es usar los parametros de salida de los que disponemos en los procedimientos.

Forma con tabla temporal:

Procedimiento 1:

Delimiter $$
Create procedure Proc_ConsultarPrecio (In Codigo int)
Begin
drop temporary table if exists TablaTemporal;
create temporary table TablaTemporal as Select Unitprice from Products where ProductID=Codigo;
End
$$
Delimiter ;

Procedimiento 2:

Delimiter $$
Create procedure Proc_InsertarDetalle (In NumOrden Int, In NumProd int, In Cantidad int, In Descuento decimal(7,2))
Begin
Declare VarPrecio decimal(7,2);
Call Proc_ConsultarPrecio(NumProd) ;
Set VarPrecio= (Select UnitPrice from TablaTemporal);
Insert into Orderdetails (OrderID, ProductID, UnitPrice, Quantity, Discount)
Values (NumOrden, NumProd, VarPrecio, Cantidad, Descuento );
drop temporary table if exists TablaTemporal;
End
$$
Delimiter ;

Forma utilizando parametros de salida del procedimiento:

Procedimiento 1:

Delimiter $$
Create Procedure proc_consultar_precio (inout precio int,In CodProd int)
Begin
select unitprice into precio from products where productId = CodProd;
End
$$
Delimiter ;

Procedimiento 2:

Delimiter $$
Create Procedure Insert_Orderdetail(IN POrderId Int(11), IN PProductID int(11), PQuantity Int(6), PDiscount double)
Begin
Declare Variable1 decimal(7,2);
Call proc_consultar_precio(Variable1, PProductID);
Insert into Orderdetails(OrderId, ProductID, UnitPrice, Quantity, Discount)
Values(POrderId,PProductID,Variable1,PQuantity,Discount);
End
$$
Delimiter ;

Para esta demostración estamos usando la base de datos de ejemplo de Northwind en Mysql que consiste en un sistema de pedidos, cuenta con las tablas Customers, Orders, OrderDetails, Products, Categories, Suppliers, Employees, entre otras.

En principio queremos crear un procedimiento que llame a otro procedimiento almacenado, así que vamos a crear dos procedimientos el primero solicita como parametro el código del cliente y contendra la instrucción para eliminar el cliente.

El segundo procedimiento también solicita el codigo del cliente y usa una condición para evaluar si el cliente tiene ordenes y si tiene indicara que no se puede eliminar el cliente pero si no tiene invocará al primer procedimiento almacenado, el código SQL debe de ser:

Procedimiento 1:
Delimiter $$
Create procedure Proc_DeleteCustomer (In Codigo varchar(5))
Begin
Delete from Customers where Customerid=Codigo;
End
$$
Delimiter ;

Procedimiento 2:

Delimiter $$
Create procedure Proc_QuitarCliente (In IDcliente varchar(5))
Begin
If (Select Count(*) from Orders where Customerid=IDCliente)>0 then
Select 'No se puede eliminar a este cliente';
else
Call Proc_DeleteCustomer (IDcliente);
end if;
End
$$
Delimiter ;

Ahora en un segundo ejercicio se necesita crear un procedimiento almacenado que inserte un nuevo registro en la tabla OrderDetails, dentro de los campos que se deben de insetar esta el Precio por Unidad al que se vende el producto pero este precio en vez de ingresarlo se debe de buscar del catalogo de productos, que es la tabla productos, a través de un procedimiento almacenado:

En resumen el primer procedimiento debe buscar el precio del producto y luego trasladarselo al segundo procedimiento, esto se puede hacer de dos formas, la primera forma es creando una tabla temporal que usen los dos procedimientos y que sirva para compartir el dato buscado. La segunda forma es usar los parametros de salida de los que disponemos en los procedimientos.

Forma con tabla temporal:

Procedimiento 1:

Delimiter $$
Create procedure Proc_ConsultarPrecio (In Codigo int)
Begin
drop temporary table if exists TablaTemporal;
create temporary table TablaTemporal as Select Unitprice from Products where ProductID=Codigo;
End
$$
Delimiter ;

Procedimiento 2:

Delimiter $$
Create procedure Proc_InsertarDetalle (In NumOrden Int, In NumProd int, In Cantidad int, In Descuento decimal(7,2))
Begin
Declare VarPrecio decimal(7,2);
Call Proc_ConsultarPrecio(NumProd) ;
Set VarPrecio= (Select UnitPrice from TablaTemporal);
Insert into Orderdetails (OrderID, ProductID, UnitPrice, Quantity, Discount)
Values (NumOrden, NumProd, VarPrecio, Cantidad, Descuento );
drop temporary table if exists TablaTemporal;
End
$$
Delimiter ;

Forma utilizando parametros de salida del procedimiento:

Procedimiento 1:

Delimiter $$
Create Procedure proc_consultar_precio (inout precio int,In CodProd int)
Begin
select unitprice into precio from products where productId = CodProd;
End
$$
Delimiter ;

Procedimiento 2:

Delimiter $$
Create Procedure Insert_Orderdetail(IN POrderId Int(11), IN PProductID int(11), PQuantity Int(6), PDiscount double)
Begin
Declare Variable1 decimal(7,2);
Call proc_consultar_precio(Variable1, PProductID);
Insert into Orderdetails(OrderId, ProductID, UnitPrice, Quantity, Discount)
Values(POrderId,PProductID,Variable1,PQuantity,Discount);
End
$$
Delimiter ;