---Uso de funciones en MYSQL

--Pensadas para realizar cálculos y devolver resultados mediante RETURN, devuelven un valor con un tipo definido.

--Pueden ser invocadas desde una consulta, por ejemplo: 
SELECT nombre_funcion(parametros) FROM tabla
--No pueden operar con transacciones

----Vocabulario básico para crear una función en MySQL:

    CREATE FUNCTION: sentencia para crear la función.

    NOMBRE_DE_LA_FUNCION: nombre de la función debe ser único en la base de datos.

    RETURNS: Especificamos el tipo de dato que vamos a retornar como INT, VARCHAR, FLOAT, etc.

    BEGIN ... END: Define el cuerpo de la función. 

    DECLARE: declarar variables.

    SET: asignar valores a variables.
	
	INTO: Se utiliza en combinación con una consulta SQL para asignar los resultados de la consulta a variables.

    RETURN: sentencia para devolver el resultado.

    PARAMETROS: son los parametros que le pasamos a la función (parametro1 INT,parametro2 FLOAT)

---Tipos de función
  --  DETERMINISTIC: Indica que la función siempre produce el mismo resultado para los mismos valores de entrada. 
  --  NO SQL: no realiza operaciones en la base de datos.
  --  READS SQL DATA: puede leer datos de la base de datos, pero no modificarlos. (Hay que indicarlo cuando sea el caso)
	

--- Estructura básica de una función MySQL
DELIMITER //
CREATE FUNCTION nombre_funcion (variable tipo)  
RETURNS tipo
BEGIN
  --INICIO DE ACCIONES
  DECLARE numero INT; -- Declara la variable numero como INT
  SELECT count(*) INTO numero FROM clientes; --Realiza una consulta para contar el número de filas en la tabla clientes y asigna el resultado a la variable numero.
  RETURN numero;
  --FIN DE ACCIONES
END//
DELIMITER ;


--Ejemplo

CREATE FUNCTION calcular_area_circulo (radio FLOAT)
RETURNS FLOAT
BEGIN
    DECLARE area FLOAT; -- Declaración de variable local
    SET area = PI() * POW(radio, 2); -- Cálculo del área
    RETURN area; -- Devolución del resultado
END;

--Llamada a la función
SELECT calcular_area_circulo(5);

--Podemos llamar a una función desde diferentes contextos, incluyendo consultas SQL, procedimientos almacenados, disparadores (triggers) y funciones definidas por el usuario. 


--Otro ejemplo función que devuelve el nombre del mes en español
DELIMITER //

CREATE FUNCTION nombre_mes(numero_mes INT) RETURNS VARCHAR(20)
BEGIN
    DECLARE nombre VARCHAR(20);
    
    CASE numero_mes
        WHEN 1 THEN SET nombre = 'Enero';
        WHEN 2 THEN SET nombre = 'Febrero';
        WHEN 3 THEN SET nombre = 'Marzo';
        WHEN 4 THEN SET nombre = 'Abril';
        WHEN 5 THEN SET nombre = 'Mayo';
        WHEN 6 THEN SET nombre = 'Junio';
        WHEN 7 THEN SET nombre = 'Julio';
        WHEN 8 THEN SET nombre = 'Agosto';
        WHEN 9 THEN SET nombre = 'Septiembre';
        WHEN 10 THEN SET nombre = 'Octubre';
        WHEN 11 THEN SET nombre = 'Noviembre';
        WHEN 12 THEN SET nombre = 'Diciembre';
        ELSE SET nombre = 'Mes no válido';
    END CASE;

    RETURN nombre;
END //

DELIMITER ;


-- Principales estructuras para controlar el flujo de código

--IF-THEN-ELSE: Permite ejecutar un bloque de código si una condición especificada es verdadera y otro bloque si la condición es falsa.

IF condición THEN
    -- Código a ejecutar si la condición es verdadera
ELSE
    -- Código a ejecutar si la condición es falsa
END IF;

--CASE: Evalúa una lista de condiciones y devuelve un valor único correspondiente a la primera condición verdadera. Se puede usar en su forma simple o en su forma de expresión, donde se puede utilizar para asignar valores a una variable.

CASE
    WHEN condición1 THEN valor1
    WHEN condición2 THEN valor2
    ...
    ELSE valor_por_defecto
END;
Ejemplo de asignación de valor mediante CASE:

Otro ejemplo:
SET variable = 
    CASE
        WHEN condición1 THEN valor1
        WHEN condición2 THEN valor2
        ...
        ELSE valor_por_defecto
    END;
	
	
--WHILE: Permite ejecutar un bloque de código repetidamente mientras una condición especificada sea verdadera.

WHILE condición DO
    -- Código a ejecutar mientras la condición sea verdadera
END WHILE;


--LOOP: Se utiliza para crear bucles que se ejecutan indefinidamente hasta que se alcanza una condición de salida.

LOOP
    -- Código a ejecutar
    IF condición_de_salida THEN
        LEAVE; -- Termina el bucle
    END IF;
END LOOP;


--ITERATE: Se utiliza dentro de un bucle para saltar a la siguiente iteración del bucle.

ITERATE; -- Salta a la siguiente iteración del bucleç


--LEAVE: Se utiliza dentro de un bucle para salir del bucle.

LEAVE; -- Sale del bucle