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

[SOLUCIONADO] Dudas creación de procedimiento

Estas en el tema de Dudas creación de procedimiento en el foro de Mysql en Foros del Web. Buenas tardes He creado un procedimiento que funciona correctamente pero me ha surgido una duda, un poco absurda pero que me gustaría despejar. En el ...
  #1 (permalink)  
Antiguo 11/05/2013, 08:07
 
Fecha de Ingreso: mayo-2008
Mensajes: 156
Antigüedad: 15 años, 11 meses
Puntos: 0
Dudas creación de procedimiento

Buenas tardes

He creado un procedimiento que funciona correctamente pero me ha surgido una duda, un poco absurda pero que me gustaría despejar.

En el procedimiento hago 3 updates, 1 delete y un insert, todos independientes entre si porque son 5 tablas diferentes, pero que en realidad hacen un todo. Es decir, si falla uno de las 5 acciones, no me gustaría que las otras 4 se ejecutaran, ya sea si falla en la primera como si falla en la 5º y última.

Me explico un poco mas:

En el procedimiento lo que hago es recoger los datos de un cliente (nombre, gasto, etc) y con esos datos voy editando los datos del mismo cliente, los datos de una factura y los datos de un producto.

Me he encontrado que por ejemplo si empiezo actualizando los datos del cliente en la tabla correspondiente y da OK, luego al pasar a actualizar otra tabla, si da error, el dato actualizado primer no vuelve a su ser. Es decir, no se comporta el procedimiento como un todo, sino que cada acción (como es normal) actua de forma independiente.

Que ocurre, que no se en caso de que una de las acciones falle, volver a dejar el estado en el que estaba el resto de tablas o terminar y no ejecutar el resto de sentencias (dependiendo del número de acción que se esté ya ejecutando)

No se si esto es posible, dado que mi intención haciendo un procedimiento es evitar el masivo código que supondría ir haciendo 5 consultas a la base de datos desde PHP.

Un saludo
  #2 (permalink)  
Antiguo 11/05/2013, 09:46
 
Fecha de Ingreso: abril-2011
Mensajes: 66
Antigüedad: 13 años
Puntos: 7
Respuesta: Dudas creación de procedimiento

Hola yosoloyo

Tengo la solucion a tu pregunta. Lo que indicas si se puede realizar, y se puede resolver de la siguiente manera:

Supongamos que tienes tus query's ordenadas en query1, query2, query3, ... ; entonces lo que tienes que hacer es editar el procedimiento almacenado y antes de la escritura de la primera query, colocar ela palabra BEGIN () (si es que programaste el procedimiento almacenado a traves de mysql), y despues de la ultima query, colocar la palabra COMMIT(). Te tendria que quedar algo asi:

BEGIN();
query1;
query2;
query3;
query4;
query5;
COMMIT();

Esto realiza realmente lo que tu deseas.

Si tienes alguna duda, comenta y te respondo dentro de lo que pueda.

Saludos y cuentame como te fue.
  #3 (permalink)  
Antiguo 12/05/2013, 04:56
 
Fecha de Ingreso: mayo-2008
Mensajes: 156
Antigüedad: 15 años, 11 meses
Puntos: 0
Respuesta: Dudas creación de procedimiento

Gracias por tu respuesta

Lo he probado pero sigue realizando todas las operaciones por separado en vez de esperar digamos a confirmar que todas son correctas y ejecutarlas todas a la vez.

Pongo un ejemplo de como lo he hecho:

Código MySQL:
Ver original
  1. CREATE PROCEDURE nombreproc(IN idprod int, IN precioprod float, IN idcli int)
  2.    UPDATE tabla1 SET aaa = aaa, bbb = bbb   WHERE idc = idcli;
  3.    INSERT INTO tabla2 (campo1, campo2, campo3) VALUES (NULL, aaa, bbb);
  4.    DELETE FROM tabla3 WHERE ccc=idprod;
  5.    UPDATE tabla4 SET ddd = ddd WHERE ddd=ddd;
  6.  

O sea, mi intención es que si por ejemplo da error en el insert, que el update a la tabla1 no se haga efectivo, o que si ese error se produce en el último update (el que se hace a la tabla4, que ni el update, insert y delete anteriores se ejecuten.

De nuevo gracias por tu respuesta
  #4 (permalink)  
Antiguo 12/05/2013, 19:25
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 4 meses
Puntos: 2658
Respuesta: Dudas creación de procedimiento

Cita:
Lo he probado pero sigue realizando todas las operaciones por separado en vez de esperar digamos a confirmar que todas son correctas y ejecutarlas todas a la vez.
Es que eso no existe en una base de datos...
No puedes ejecutarlas todas a la vez, precisamente por si existen dependencias funcionales entre ellas. MySQL no puede adivinarlo, eso lo sabes únicamente tu. Por eso el modelo de proceso no soporta ese nivel de concurrencia.
De todos modos si el problema que que o se cumplan todas o no se cumpla ninguna, la cosa ya fue resuelta hace años: Para eso existen las transacciones... La creación de operaciones atómicas permite precisamente establecer que una o más acciones se realicen o se deshagan.
Claro que tiene como restricción que las tablas usadas, en el caso de MySQL, deben ser sí o sí InnoDB, y no pueden ser MyISAM.

Concurrencia en MySQL

Una aclaración, para despejar un detalle: El hecho de que en un SP uses BEGIN/END no implica que estés usando transacciones, si la transacción no fue declarada. Por default, las sentencias DML en MySQL son de ejecución inmediata, estén o no dentro de un SP. Pero si dentro de un SP se crea y confirma una transacción, la cosa es diferente.

Lee del tema, y luego veremos.
__________________
¿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 13/05/2013, 10:22
 
Fecha de Ingreso: abril-2011
Mensajes: 66
Antigüedad: 13 años
Puntos: 7
Respuesta: Dudas creación de procedimiento

@yosoloyo: los pasos que te indique estan correctos, solo que de acuerdo a la escritura de tu procedimiento, esribiste mal lo que te indique:

- en BEGIN, deberias haber escritor BEGIN(); porque es una funcion.
- en donde pusiste COMMIT, el mismo caso.
- en donde dice START TRANSACTION esta demas eso.
- creo que te confundiste con la declaracion de BEGIN ... END que se realiza para el cierre de un SP, te dejo como deberia estar esrito:

Código MySQL:
Ver original
  1. CREATE PROCEDURE nombreproc(IN idprod INT, IN precioprod FLOAT, IN idcli INT)
  2.   BEGIN();
  3.    UPDATE tabla1 SET aaa = aaa, bbb = bbb   WHERE idc = idcli;
  4.    INSERT INTO tabla2 (campo1, campo2, campo3) VALUES (NULL, aaa, bbb);
  5.    DELETE FROM tabla3 WHERE ccc=idprod;
  6.    UPDATE tabla4 SET ddd = ddd WHERE ddd=ddd;
  7.  
  8.  COMMIT();

pruebalo ahora y te resultara.

Ahora voy a realizar una aclaracion. Lo quete menciona gnzsoloyo, en parte es correcto, porque no existe lo que tu qieres realizar que se ejecuten todas a la vez, solo se iran ejecutando en el orden especificado por ti a la hora de programar el SP o las transacciones que vayas incluyendo, pero lo que yo te indique que hicieras cumple con lo que requieres, paso a explicar el funcionamiento de lo que mencione.

Cuando tu inicias una transaccion con BEGIN(); y tiene todas esas sentencias sql que ingresan, modifican o eliminan datos, hasta que tu no le des la instruccion de COMMIT(); estas consultas jamas se ejecutaran realmente en tus bases de datos, sino que solo se ejecutaran en las tablas virtuales que crea MySQL para tales efectos. Si en algun caso una instruccion ha lanzado algun error ya sea porque uno de los campos que declaraste no se encuentra en la base de datos, lo que realiza MySQL es una llamada a la funcion ROLLBACK(), que lo que hace es deshacer todo lo realizado, y no lo hace efectivo en tus bases de datos. De forma contraria, si todas las instrucciones se han ejecutado de forma correcta, y se encuentra la funcion COMMIT(); todos los cambios los realiza ahora de forma fisica en tus bases de datos y lo refleja para ti exitosamente.

Recuerda, las consultas se ejecutaran en orden.

Cita:
Claro que tiene como restricción que las tablas usadas, en el caso de MySQL, deben ser sí o sí InnoDB, y no pueden ser MyISAM.
Esto es totalmente correcto, para realizar lo que te mencione, todas las tablas asociadas deben ser InnoDB.

Cita:
las sentencias DML en MySQL son de ejecución inmediata,
Esto se cumple gracias al trabajo de los desarrolladores, quienes implementaron el AutoCommit, y el AutoBegin en los motores de base de datos, que nos permite poder escribir cualquier sentencia de forma que sea sencilla y como la conocemos todos en la actualidad, porque si no fuera asi, todos deberiamos escribir:

BEGIN();
query;
COMMIT();
  #6 (permalink)  
Antiguo 13/05/2013, 14:13
 
Fecha de Ingreso: mayo-2008
Mensajes: 156
Antigüedad: 15 años, 11 meses
Puntos: 0
Respuesta: Dudas creación de procedimiento

Gracias a ambos por las respuestas. gnzsoloyo siempre es duro en sus respuestas pero también ayuda.

Me expliqué mal, ya se que no se pueden ejecutar todas a la vez, sería incongruente. Era parte de una explicación mal dada por mi parte intentando explicarlo lo mejor posible.

Funciona de forma correcta como decis con InnoDB que es como lo tengo en modo local, pero en un servidor gratuito que tengo en internet no soporta InnoDB y tengo que trabajar con MylSAM, por lo que bueno, buscaré otra alternativa.

De nuevo gracias por la ayuda, doy el tema por finalizado. Un saludo a ambos

Etiquetas: creación, dudas, insert, php, procedimiento, tabla
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 18:37.