
--Stored Procedures--Procedimientos almacenados
	
-- Que son ?
-- Son bloques de código SQL que se almacenan en la base de datos y se pueden llamar y ejecutar repetidamente(funciones????)

--Direfencias con las funciones
--Tipo de retorno:
---Funciones: Devuelven un único valor como resultado y pueden ser utilizadas en cualquier lugar donde se espera una expresión.
---Procedimientos almacenados: No devuelven valores explícitos, aunque pueden producir resultados indirectos, como modificar datos en tablas o generar resultados a través de cursores de salida.

--Uso en consultas:
---Funciones: Pueden ser invocadas directamente dentro de consultas SELECT, INSERT, UPDATE o DELETE.
---Procedimientos almacenados: No pueden ser directamente invocados dentro de consultas, pero pueden ser llamados desde aplicaciones o desde otros procedimientos almacenados.


--Cambios en la base de datos
---Funciones: No pueden realizar operaciones de modificación de datos directamente sobre las tablas.
---Procedimientos almacenados: Pueden contener sentencias SQL que modifican datos en las tablas, como INSERT, UPDATE o DELETE.

--Parametros
---Funciones: Pueden aceptar parámetros de entrada y devolver un valor como resultado.
---Procedimientos almacenados: Pueden aceptar parámetros de entrada y/o salida, pero no devuelven un valor explícito.	


-- Vocabulario 

    CREATE PROCEDURE: crear un nuevo procedimiento.

    BEGIN y END: para delimitar el cuerpo del procedimiento almacenado, donde se encuentra las instrucciones a ejecutar.

    DELIMITER: para cambiar el delimitador de sentencia temporalmente)

    DECLARE: para declarar variables locales dentro del procedimiento almacenado.

    IN indica que el parámetro es de entrada, 
	OUT indica que es de salida 
	INOUT indica que es tanto de entrada como de salida.

    IF, ELSEIF, ELSE, END IF: para condicionar la ejecución de bloques.

    CASE: para evaluar múltiples condiciones.

    LOOP: para crear un bucle infinito.
    
	REPEAT: para ejecutar bucles.
	
    LEAVE: para salir de un bucle o de un bloque de código etiquetado.

    ITERATE: para saltar a la siguiente iteración de un bucle.

    RETURN: para devolver un valor de un procedimiento almacenado.

    CALL: para llamar y ejecutar un procedimiento almacenado.


--Para que ?	
---Procedimiento para insertar datos:
	
	DELIMITER //

CREATE PROCEDURE insertar_usuario(
    IN p_nombre VARCHAR(50),
    IN p_apellido VARCHAR(50),
    IN p_email VARCHAR(100)
)
BEGIN
    INSERT INTO usuarios(nombre, apellido, email) VALUES (p_nombre, p_apellido, p_email);
END //

DELIMITER ;



---Procedimiento para actualizar datos:

DELIMITER //

CREATE PROCEDURE actualizar_usuario(
    IN p_id INT,
    IN p_nombre VARCHAR(50),
    IN p_apellido VARCHAR(50),
    IN p_email VARCHAR(100)
)
BEGIN
    UPDATE usuarios SET nombre = p_nombre, apellido = p_apellido, email = p_email WHERE id = p_id;
END //

DELIMITER ;



---Procedimiento para eliminar datos:

DELIMITER //

CREATE PROCEDURE eliminar_usuario(
    IN p_id INT
)
BEGIN
    DELETE FROM usuarios WHERE id = p_id;
END //

DELIMITER ;



---Procedimiento para obtener datos filtrados:

DELIMITER //

CREATE PROCEDURE obtener_usuarios_por_apellido(
    IN p_apellido VARCHAR(50)
)
BEGIN
    SELECT * FROM usuarios WHERE apellido = p_apellido;
END //

DELIMITER ;



---Otro ejemplo con parametros de entrada
CREATE PROCEDURE calcular_precio_total(
    IN producto_id INT,
    IN cantidad_comprada INT,
    OUT precio_total DECIMAL(10,2)
)
BEGIN
    -- Declarar una variable para almacenar el precio del producto
    DECLARE precio_unitario DECIMAL(10,2);

    -- Obtener el precio unitario del producto
    SELECT precio INTO precio_unitario FROM productos WHERE id = producto_id;

    -- Calcular el precio total
    SET precio_total = precio_unitario * cantidad_comprada;
END;


---Llamar al procedimiento
CALL calcular_precio_total(1, 5, @precio_total);
SELECT @precio_total;





---Procedimiento para realizar cálculos y retornar resultados:
DELIMITER //

CREATE PROCEDURE calcular_total_pedidos_periodo(
    IN p_fecha_inicio DATE,
    IN p_fecha_fin DATE,
    OUT total_pedidos DECIMAL(10,2)
)
BEGIN
    SELECT SUM(total) INTO total_pedidos FROM pedidos WHERE fecha BETWEEN p_fecha_inicio AND p_fecha_fin;
END //

DELIMITER ;

---Llamada al procedimiento
CALL calcular_total_pedidos_periodo('2024-01-01', '2024-03-31', @total_pedidos);
SELECT @total_pedidos;




