Jump to content

Problema de bloque de query


Recommended Posts

Hola, nos ha pasado varias veces que la función de updateReservedProductQuantity en esta query 

UPDATE {table_prefix}stock_available sa SET sa.reserved_quantity = ( SELECT SUM(od.product_quantity - od.product_quantity_refunded) FROM {table_prefix}orders o INNER JOIN {table_prefix}order_detail od ON od.id_order = o.id_order INNER JOIN {table_prefix}order_state os ON os.id_order_state = o.current_state WHERE o.id_shop = :shop_id AND os.shipped != 1 AND ( o.valid = 1 OR ( os.id_order_state != :error_state AND os.id_order_state != :cancellation_state ) ) AND sa.id_product = od.product_id AND sa.id_product_attribute = od.product_attribute_id GROUP BY od.product_id, od.product_attribute_id ) WHERE sa.id_shop = :shop_id

se bloquea la BBDD por culpa de esta query. Esto provoca que algunos pedidos se generen pero sin productos, cobrando al cliente y todo, con lo que conlleva reparar este problema.

Hemos visto una manera de arreglar esta query, os la pongo aquí 

https://github.com/PrestaShop/PrestaShop/pull/28854

La otra es optimizar la query haciendo una temporal 

El cálculo de reserved_quantity se hace solo una vez en la tabla temporal.

CREATE TEMPORARY TABLE temp_reserved_stock AS
SELECT 
    od.product_id, 
    od.product_attribute_id,
    SUM(od.product_quantity - od.product_quantity_refunded) AS reserved_quantity
FROM {table_prefix}orders o
INNER JOIN {table_prefix}order_detail od ON od.id_order = o.id_order
INNER JOIN {table_prefix}order_state os ON os.id_order_state = o.current_state
WHERE o.id_shop = :shop_id 
AND os.shipped != 1 
AND (o.valid = 1 OR (os.id_order_state NOT IN (:error_state, :cancellation_state)))
GROUP BY od.product_id, od.product_attribute_id;

y luego la actualización usa JOIN en lugar de subqueries anidadas

UPDATE {table_prefix}stock_available sa
INNER JOIN temp_reserved_stock temp ON sa.id_product = temp.product_id 
AND sa.id_product_attribute = temp.product_attribute_id
SET sa.reserved_quantity = temp.reserved_quantity
WHERE sa.id_shop = :shop_id;

¿Cuál creéis que es mejor opción?

Saludos y gracias 

 

 

Link to comment
Share on other sites

  On 3/25/2025 at 11:47 AM, five said:

UPDATE {table_prefix}stock_available sa SET sa.reserved_quantity = ( SELECT SUM(od.product_quantity - od.product_quantity_refunded) FROM {table_prefix}orders o INNER JOIN {table_prefix}order_detail od ON od.id_order = o.id_order INNER JOIN {table_prefix}order_state os ON os.id_order_state = o.current_state WHERE o.id_shop = :shop_id AND os.shipped != 1 AND ( o.valid = 1 OR ( os.id_order_state != :error_state AND os.id_order_state != :cancellation_state ) ) AND sa.id_product = od.product_id AND sa.id_product_attribute = od.product_attribute_id GROUP BY od.product_id, od.product_attribute_id ) WHERE sa.id_shop = :shop_id

 

Expand  

Esta consulta no parece ser correcta.

Debería incluir también una condición de ID de producto en la consulta. Esta consulta establecerá el stock de todos los productos en un único valor (por ejemplo, 10 para todos los productos), calculado mediante una subconsulta.

Link to comment
Share on other sites

  On 3/25/2025 at 12:06 PM, Knowband Plugins said:

El segundo enfoque parece más lógico.

Expand  

Gracias por la respuesta, la primera es este enlace de GIT

https://github.com/PrestaShop/PrestaShop/pull/28854

La query es el problema, pero tenemos 2 maneras de arreglar la primera es este GIT que he pasado que son estas modificaciones en el archivo 

https://github.com/PrestaShop/PrestaShop/pull/28854/files

y la segunda es la query temporal,

¿Cuál crees?

Saludos 

 

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...