No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Ejecutar un stored procedure

24/25
Recursos

Aportes 11

Preguntas 3

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

Yo creyendo que se SQL y veo esto jajaja

Para los que estén trabajando con Postgres aquí le dejo el store procedure

CREATE OR REPLACE PROCEDURE take_random_pizza_order(IN id_customer VARCHAR(15), IN method CHAR(1), OUT order_taken BOOLEAN)
AS '
DECLARE
    id_random_pizza INT;
    price_random_pizza DECIMAL(5,2);
    price_with_discount DECIMAL(5,2);
    with_errors BOOLEAN DEFAULT FALSE;
    last_order_id INT;
BEGIN
    BEGIN
        SELECT id_pizza, price
        INTO id_random_pizza, price_random_pizza
        FROM pizza
        WHERE available = 1
        ORDER BY RANDOM()
        LIMIT 1;
        
        price_with_discount := price_random_pizza - (price_random_pizza * 0.20);
        
        BEGIN
            -- Realizar los inserts dentro del bloque BEGIN...END
            BEGIN
                -- Insertar en la tabla pizza_order
                INSERT INTO pizza_order (id_customer, date, total, method, additional_notes)
                VALUES (id_customer, CURRENT_DATE, price_with_discount, method, ''20% OFF PIZZA RANDOM PROMOTION'');
                
                -- Obtener el último ID insertado en pizza_order
                last_order_id := currval(''pizza_order_id_order_seq'');
                
                -- Insertar en la tabla order_item
                INSERT INTO order_item (id_item, id_order, id_pizza, quantity, price)
                VALUES (1, last_order_id, id_random_pizza, 1, price_random_pizza);
            EXCEPTION WHEN OTHERS THEN
                with_errors := TRUE;
                -- Deshacer la transacción en caso de error
                ROLLBACK;
            END;
            
            IF with_errors THEN 
                order_taken := FALSE;
            ELSE 
                order_taken := TRUE;
            END IF;
        END;
    EXCEPTION WHEN OTHERS THEN
        with_errors := TRUE;
    END;
    
    IF with_errors THEN 
        order_taken := FALSE;
    END IF;
END;
' LANGUAGE plpgsql;

Tengan mucho cuidado cuando no incluyan la anotación @Transactional en el método saveRandomOrder que llama al Stored Procedure, ya que me di cuenta que aunque devuelve un error 500, la inserción de la orden en la base de datos se sigue haciendo.

Para los que trabajen con Postgres, aqui les dejo una correccion del método y las instrucciones para que funcione en la versión 13. En lugar de usar una variable OUT, cambiamos order_taken por INOUT y para asegurarme le pasé un valor por defecto.

Script para postgresql

CREATE OR REPLACE PROCEDURE take_random_pizza_order(IN id_customer VARCHAR(15), IN method CHAR(1), INOUT order_taken BOOLEAN DEFAULT FALSE)
AS $$
DECLARE
    id_random_pizza INT;
    price_random_pizza DECIMAL(5,2);
    price_with_discount DECIMAL(5,2);
    with_errors BOOLEAN DEFAULT FALSE;
    last_order_id INT;
BEGIN
    BEGIN
        SELECT id_pizza, price
        INTO id_random_pizza, price_random_pizza
        FROM pizza
        WHERE available = 1
        ORDER BY RANDOM()
        LIMIT 1;
        
        price_with_discount := price_random_pizza - (price_random_pizza * 0.20);
        
        BEGIN
            -- Realizar los inserts dentro del bloque BEGIN...END
            BEGIN
                -- Insertar en la tabla pizza_order
                INSERT INTO pizza_order (id_customer, date, total, method, additional_notes)
                VALUES (id_customer, CURRENT_DATE, price_with_discount, method, '20% OFF PIZZA RANDOM PROMOTION')
                RETURNING id_order INTO last_order_id;
                
                -- Insertar en la tabla order_item
                INSERT INTO order_item (id_item, id_order, id_pizza, quantity, price)
                VALUES (1, last_order_id, id_random_pizza, 1, price_random_pizza);
                
                EXCEPTION WHEN OTHERS THEN
                with_errors := TRUE;
            END;
            
            IF with_errors THEN 
                order_taken := FALSE;
            ELSE 
                order_taken := TRUE;
            END IF;
        END;
    EXCEPTION WHEN OTHERS THEN
        with_errors := TRUE;
    END;
    
    IF with_errors THEN 
        order_taken := FALSE;
    END IF;
END;
$$ LANGUAGE plpgsql;

OrderRepository.java

    @Procedure(value = "take_random_pizza_order")
    Boolean saveRandomOrder(@Param("id_customer") String idCustomer, @Param("method") String method);

OrderService.java

    @Transactional
    @Modifying(clearAutomatically = true)
    public Boolean saveRandomOrder(RandomOrderDto randomOrderDto) {
        return this.orderRepository.saveRandomOrder(randomOrderDto.getIdCustomer(), randomOrderDto.getMethod());
    }

En caso quieran verlo a detalle dejo mi repo
https://github.com/JessAT18/PlatziPizzeria.git

Listo ✅ Recuerden usar el comando "USE pizzeria;" para establecer en cual BD ejecutarán el storeprocedure

quiero compartir por aquí algo que les podria ser interesante y quizas sume valor para los que estan usando versiones de java 16 en adelante es el uso de Java Records, para usarlos con Lode Dto

public record RandomOrderDto(Long idCustomer, String method) {
}

y para llamarle es sencillo de hacer esto;

  return this.orderRepository.saveRandomOrder(randomOrderDto.idCustomer(),randomOrderDto.method());
Muy buen curso, aunque termine con hambre jajaja
Excelente el curso, me ha encantado.

Si no les funciona el script del procedure en mysql pueden usar este, les recomiendo borrar manualmente el procedure y ejecutar.

<CREATE PROCEDURE take_random_pizza_order(
    IN id_customer VARCHAR(15),
    IN method CHAR(1),
    OUT order_taken BOOL
)
BEGIN
    DECLARE id_random_pizza INT;
    DECLARE price_random_pizza DECIMAL(5,2);
    DECLARE price_with_discount DECIMAL(5,2);
    
    DECLARE WITH_ERRORS BOOL DEFAULT FALSE;
    
    -- Manejador de errores fuera del bloque principal
    DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
    BEGIN
        SET WITH_ERRORS = TRUE;
    END;
    
    SELECT id_pizza, price
    INTO id_random_pizza, price_random_pizza
    FROM pizza
    WHERE available = 1
    ORDER BY RAND()
    LIMIT 1;
    
    SET price_with_discount = price_random_pizza - (price_random_pizza * 0.20);
    
    START TRANSACTION;
    
    INSERT INTO pizza_order (id_customer, date, total, method, additional_notes)
    VALUES (id_customer, SYSDATE(), price_with_discount, method, '20% OFF PIZZA RANDOM PROMOTION');
    
    INSERT INTO order_item (id_item, id_order, id_pizza, quantity, price)
    VALUES (1, LAST_INSERT_ID(), id_random_pizza, 1, price_random_pizza);
    
    IF WITH_ERRORS THEN 
        SET order_taken = FALSE;
        ROLLBACK;
    ELSE 
        SET order_taken = TRUE;
        COMMIT;
    END IF;
    
    SELECT order_taken;
END;
> 
Listo ✅

✅