Foros del Web » Programación para mayores de 30 ;) » Bases de Datos General » Mysql »

Stored Procedure

Estas en el tema de Stored Procedure en el foro de Mysql en Foros del Web. Hola compañeros estoy haciendo un Stored Procedure que cambie el estado de una reserva guardada en la BD al transcurrir una hora este es el ...
  #1 (permalink)  
Antiguo 10/02/2015, 09:53
 
Fecha de Ingreso: febrero-2014
Mensajes: 48
Antigüedad: 10 años, 9 meses
Puntos: 0
Stored Procedure

Hola compañeros estoy haciendo un Stored Procedure que cambie el estado de una reserva guardada en la BD al transcurrir una hora este es el SP:

Código MySQL:
Ver original
  1. -------------------------------------------------------------------------------------------------
  2.  
  3. DROP PROCEDURE IF EXISTS tumba_reserva;
  4.  
  5. CREATE PROCEDURE tumba_reserva ()
  6.  
  7. DECLARE hora_actual TIME;
  8.  
  9.  
  10. SET hora_actual = CURTIME();
  11.  
  12.  
  13. SELECT ( if ( numero_vaucher = '' OR numero_vaucher is Null, 0 )And codigo_estatus_reserva = '2'), hora_reserva
  14. FROM crb_reservacion
  15.  
  16. IF (hora_reserva - hora_actual) >= 1) THEN
  17.  
  18. UPDATE crb_reservacion Where codigo_estatus_reserva = 4;
  19.  
  20.  
  21. -------------------------------------------------------------------------------------------------

Por algún motivo me da este error cuando intento agregarlo a la bd:


Código MySQL:
Ver original
  1. CREATE PROCEDURE tumba_reserva ()
  2.  
  3. DECLARE hora_actual TIME;
  4. MySQL ha dicho: Documentación
  5.  
  6. #1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 4

He intentado varias modificaciones y nada, les agradezco su ayuda, gracias de antemano.

Última edición por gnzsoloyo; 10/02/2015 a las 10:34
  #2 (permalink)  
Antiguo 10/02/2015, 10:45
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 17 años
Puntos: 2658
Respuesta: Stored Procedure

Hay más de un error...
1) Un SP no puede contener una consulta sin asignar resultados a variables, si no es la última linea del body. Y eso sólo tiene sentido si la consulta es el resultado esperado en pantalla, o la salida de datos que se tomará desde un programa.
2) A tu IF() le falta la condición de FALSE, por lo que está mal escrito.
3) No estás cerrando la linea de ese select con el terminador de sentencias, por lo que ni siquiera debe estar compilando.
4) Ese script sólo podría cargarse desde una aplicación. DE pretender hacerlo desde consola de MySQL fallará, y si lo haces desde phpMyadmin también, a menos que determines un delimiter distinto.
Para compilar en consola de MySQL:
Código MySQL:
Ver original
  1. DROP PROCEDURE IF EXISTS tumba_reserva;
  2. DELIMITER $$
  3.  
  4. CREATE PROCEDURE tumba_reserva ()
  5.     DECLARE hora_actual TIME;
  6.     DECLARE hora_res TIME;
  7.  
  8.     SET hora_actual = CURTIME();
  9.     SELECT (IF((numero_vaucher = '' OR numero_vaucher IS NULL) AND codigo_estatus_reserva = 2), hora_reserva, 'Aca va la salida por FALSE')
  10. INTO hora_res
  11.     FROM crb_reservacion;
  12.  
  13.     IF TIMESTAMPDIFF(, HOUR, hora_res, hora_actual) >= 1 THEN
  14.         UPDATE crb_reservacion WHERE codigo_estatus_reserva = 4;
  15.     END IF;
  16. END$$
  17.  
  18. DELIMITER ;

Aclaremos una cosa, este código no garantiza que funcione bien, solo no debería dar error al compilar. No lo garantiza, porque a mi entender está mal pensado, ya que la consulta que pones devolverá múltiples registros, por lo que el INTO no funcionará, y el UPDATE está actualizando todos los registros que existan con esa condición, lo que a mi entender es ilógico.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #3 (permalink)  
Antiguo 10/02/2015, 11:17
 
Fecha de Ingreso: febrero-2014
Mensajes: 48
Antigüedad: 10 años, 9 meses
Puntos: 0
Respuesta: Stored Procedure

Cita:
Iniciado por gnzsoloyo Ver Mensaje
Hay más de un error...
1) Un SP no puede contener una consulta sin asignar resultados a variables, si no es la última linea del body. Y eso sólo tiene sentido si la consulta es el resultado esperado en pantalla, o la salida de datos que se tomará desde un programa.
2) A tu IF() le falta la condición de FALSE, por lo que está mal escrito.
3) No estás cerrando la linea de ese select con el terminador de sentencias, por lo que ni siquiera debe estar compilando.
4) Ese script sólo podría cargarse desde una aplicación. DE pretender hacerlo desde consola de MySQL fallará, y si lo haces desde phpMyadmin también, a menos que determines un delimiter distinto.
Para compilar en consola de MySQL:
Código MySQL:
Ver original
  1. DROP PROCEDURE IF EXISTS tumba_reserva;
  2. DELIMITER $$
  3.  
  4. CREATE PROCEDURE tumba_reserva ()
  5.     DECLARE hora_actual TIME;
  6.     DECLARE hora_res TIME;
  7.  
  8.     SET hora_actual = CURTIME();
  9.     SELECT (IF((numero_vaucher = '' OR numero_vaucher IS NULL) AND codigo_estatus_reserva = 2), hora_reserva, 'Aca va la salida por FALSE')
  10. INTO hora_res
  11.     FROM crb_reservacion;
  12.  
  13.     IF TIMESTAMPDIFF(, HOUR, hora_res, hora_actual) >= 1 THEN
  14.         UPDATE crb_reservacion WHERE codigo_estatus_reserva = 4;
  15.     END IF;
  16. END$$
  17.  
  18.  
  19.  
  20. DELIMITER ;

Aclaremos una cosa, este código no garantiza que funcione bien, solo no debería dar error al compilar. No lo garantiza, porque a mi entender está mal pensado, ya que la consulta que pones devolverá múltiples registros, por lo que el INTO no funcionará, y el UPDATE está actualizando todos los registros que existan con esa condición, lo que a mi entender es ilógico.

Gracias por responder amigo, estoy empezando a trabajar con los SP así que no estoy muy diestro en eso por eso los errores. Te explico lo que necesito:

Tengo una cantidad de reservas X hechas por usuarios en la BD, las cuales entran con un estatus, si el numero de vaucher es rellenado en el formulario, la reserva ingresa con estatus '1' pendiente, hasta que ese numero de vaucher se verifique en el banco y el mismo administrador mediante un panel procesa la reserva y el estatus cambia automáticamente a '3' mediante un Update y queda "procesada". El caso contrario es que la reserva ingrese a la BD sin numero de vaucher, en este caso ingresa con estatus '2' que significa "Sin Vaucher". El SP debe tomar la hora_reserva de la bd que es la fecha que se guarda apenas el usuario ingresa la reserva (hora de su servidor) y restarla con la hora actual de manera que todas las reservas que estén en la bd en estatus '2' "sin vaucher" al transcurrir una hora o x tiempo si el usuario no la completa pasen a estado '4' - cancelada se actualice la tabla reservacion y las fechas(fecha_llegada y fecha_salida) también se actualicen a 0000-00-00 para poder ser liberadas, el SP debe consultar a la BD cada 30 minutos.
  #4 (permalink)  
Antiguo 10/02/2015, 11:51
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 17 años
Puntos: 2658
Respuesta: Stored Procedure

Esta es la parte relevante:
Cita:
El SP debe tomar la hora_reserva de la bd que es la fecha que se guarda apenas el usuario ingresa la reserva (hora de su servidor) y restarla con la hora actual de manera que todas las reservas que estén en la bd en estatus '2' "sin vaucher" al transcurrir una hora o x tiempo si el usuario no la completa pasen a estado '4' - cancelada se actualice la tabla reservacion y las fechas(fecha_llegada y fecha_salida) también se actualicen a 0000-00-00 para poder ser liberadas, el SP debe consultar a la BD cada 30 minutos.
En esencia, si entendí bien, cada 30 minutos todas las reservas en estado 4, y sin voucher, se cancelar.
Si esto es así, ni siquiera necesitas un SP. En MySQL usarías un EVENT, que permite correr un proceso programado en modo automático. Ese EVENT contendría sólo una linea:
Código MySQL:
Ver original
  1. UPDATE crb_reservacion
  2. SET codigo_estatus_reserva = 4, fecha = DATE('0000-00-00'),
  3. WHERE codigo_estatus_reserva = 2
  4.     AND TIMESTAMPDIFF (HOUR, fecha, NOW() >=1;
Esto, suponiendo que tienes un solo campo de fecha que guarda la hora. De lo contrario las condiciones se complican un poco, pero la idea sería:
Código MySQL:
Ver original
  1. UPDATE crb_reservacion
  2. SET codigo_estatus_reserva = 4, fecha = DATE('0000-00-00'),
  3. WHERE codigo_estatus_reserva = 2
  4.     AND TIMEDIFF(CURTIME(), hora_reserva)>=TIME('01:00:00')  AND fecha_reserva = CURDATE();
Esta segunda opcion no cubre la posibilidad de que la reserva se haya realizado entre las 23:00:00 de un día y el pago antes de la 01:00:00 del otro día. Es un caso que hay que analizar.

Si la idea es que aprendas a usar SP, y quieres recorrer el resultado de una consulta, deberás avanzar en varios temas.
Lee esta FAQ de este mismo foro: http://www.forosdelweb.com/f86/faqs-...1/#post4209262
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #5 (permalink)  
Antiguo 10/02/2015, 21:32
 
Fecha de Ingreso: febrero-2014
Mensajes: 48
Antigüedad: 10 años, 9 meses
Puntos: 0
Respuesta: Stored Procedure

Cita:
Iniciado por gnzsoloyo Ver Mensaje
Esta es la parte relevante:

En esencia, si entendí bien, cada 30 minutos todas las reservas en estado 4, y sin voucher, se cancelar.
Si esto es así, ni siquiera necesitas un SP. En MySQL usarías un EVENT, que permite correr un proceso programado en modo automático. Ese EVENT contendría sólo una linea:
Código MySQL:
Ver original
  1. UPDATE crb_reservacion
  2. SET codigo_estatus_reserva = 4, fecha = DATE('0000-00-00'),
  3. WHERE codigo_estatus_reserva = 2
  4.     AND TIMESTAMPDIFF (HOUR, fecha, NOW() >=1;
Esto, suponiendo que tienes un solo campo de fecha que guarda la hora. De lo contrario las condiciones se complican un poco, pero la idea sería:
Código MySQL:
Ver original
  1. UPDATE crb_reservacion
  2. SET codigo_estatus_reserva = 4, fecha = DATE('0000-00-00'),
  3. WHERE codigo_estatus_reserva = 2
  4.     AND TIMEDIFF(CURTIME(), hora_reserva)>=TIME('01:00:00')  AND fecha_reserva = CURDATE();
Esta segunda opcion no cubre la posibilidad de que la reserva se haya realizado entre las 23:00:00 de un día y el pago antes de la 01:00:00 del otro día. Es un caso que hay que analizar.

Si la idea es que aprendas a usar SP, y quieres recorrer el resultado de una consulta, deberás avanzar en varios temas.
Lee esta FAQ de este mismo foro: http://www.forosdelweb.com/f86/faqs-...1/#post4209262
Gracias por responder amigo. De hecho si, son dos fechas y realmente el plazo que quiero darle al usario es de 24 horas. Leeré el link que me mandaste sin embargo te pregunto, ¿Los últimos dos ejemplos que me mandaste son eventos en mysql?, si lo son, me parece que son inclusive más eficientes que un SP con menos código, tampoco he trabajado nunca con eventos ni triggers, ni jobs, estoy empezando a indagar. La hora de la reserva no se guarda en la misma variable que la fecha, es decir no es datetime la variable las fechas son campos a parte y la hora de la reserva también.
  #6 (permalink)  
Antiguo 11/02/2015, 05:51
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 17 años
Puntos: 2658
Respuesta: Stored Procedure

Cita:
¿Los últimos dos ejemplos que me mandaste son eventos en mysql
No exactamente. Son ejemplos de lo que el EVENT debería contener (ver 13.1.11 CREATE EVENT Syntax). Su codigo sería mas o menos asi
Código MySQL:
Ver original
  1. CREATE EVENT cancelarreservas
  2.     ON EVERY DAY
  3.     DO
  4.       UPDATE crb_reservacion
  5.       SET codigo_estatus_reserva = 4, fecha = DATE('0000-00-00')
  6.       WHERE codigo_estatus_reserva = 2
  7.           AND TIMESTAMPDIFF (DAY, fecha, NOW()) >=1;

También se puede hacer que se invoque a un SP que haga una tarea más larga:
Código MySQL:
Ver original
  1. CREATE EVENT cancelarreservas
  2.     ON EVERY DAY
  3.     DO
  4.       CALL update_reservas;
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #7 (permalink)  
Antiguo 11/02/2015, 09:04
 
Fecha de Ingreso: febrero-2014
Mensajes: 48
Antigüedad: 10 años, 9 meses
Puntos: 0
Respuesta: Stored Procedure

Cita:
Iniciado por gnzsoloyo Ver Mensaje
No exactamente. Son ejemplos de lo que el EVENT debería contener (ver 13.1.11 CREATE EVENT Syntax). Su codigo sería mas o menos asi
Código MySQL:
Ver original
  1. CREATE EVENT cancelarreservas
  2.     ON EVERY DAY
  3.     DO
  4.       UPDATE crb_reservacion
  5.       SET codigo_estatus_reserva = 4, fecha = DATE('0000-00-00')
  6.       WHERE codigo_estatus_reserva = 2
  7.           AND TIMESTAMPDIFF (DAY, fecha, NOW()) >=1;

También se puede hacer que se invoque a un SP que haga una tarea más larga:
Código MySQL:
Ver original
  1. CREATE EVENT cancelarreservas
  2.     ON EVERY DAY
  3.     DO
  4.       CALL update_reservas;
Entiendo, ahora bien, ¿con dos fechas sería exactamente igual o habría problemas con el Date?. Ya que la función Date toma siempre la primera fecha.
  #8 (permalink)  
Antiguo 11/02/2015, 09:12
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 17 años
Puntos: 2658
Respuesta: Stored Procedure

Bueno, ¿como sería un ejemplo de las dos fechas que mencionas? ¿pertenecen a la misma tabla?
Muestrame un ejemplo del caso, y veamos como construir una sola query o un SP.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #9 (permalink)  
Antiguo 11/02/2015, 11:51
 
Fecha de Ingreso: febrero-2014
Mensajes: 48
Antigüedad: 10 años, 9 meses
Puntos: 0
Respuesta: Stored Procedure

Cita:
Iniciado por gnzsoloyo Ver Mensaje
Bueno, ¿como sería un ejemplo de las dos fechas que mencionas? ¿pertenecen a la misma tabla?
Muestrame un ejemplo del caso, y veamos como construir una sola query o un SP.
Correcto, esencialmente la consulta del SP necesita de 4 campos de la tabla reservación:


1) fecha_inicio ---> tipo (Date)
2) fecha_fin ---> tipo (Date)
3) hora_reserva ---> tipo (Time) <--- Con este campo que es la hora en que el usuario realizo la reserva, lo comparamos con la hora actual
4) codigo_estatus_reserva que de por si, ya le establecemos al SP que todas las reservas con código '2' = "sin vaucher" de la tabla reservación luego de 24 horas de que la reserva permanezca así (sin vaucher) en la tabla, su estatus sea actualizado a '4' ---> "cancelada" y la fecha_inicio y fecha_fin se actualicen a 0000-00-00 para que sean liberadas esas fechas.

Etiquetas: procedure, select, sql, stored, update
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 19:20.