VeneHosting.com :: Tu Hosting en Venezuela

Autor Tema: Triggers en Mysql  (Leído 641 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado tierrarara

  • Usuario Junior
  • **
  • Mensajes: 85
  • Puntuación: 3
    • Ver Perfil
    • Rare Earth
Triggers en Mysql
« : 30 de junio de 2011, 03:08:42 pm »
Tengo el siguiente procedimiento
el cual me funciona bien, solo quiero compartir mi experiencia con uds y contarles mi duda

Código: [Seleccionar]
DROP TRIGGER IF EXISTS trg_ai_op_event_list;
delimiter //
CREATE TRIGGER trg_ai_op_event_list
AFTER INSERT ON op_event_list

for each row
BEGIN
-- agregar si el usuario recibe el tipo de notificaion
DECLARE done INT DEFAULT 0;
DECLARE f_id INT;
DECLARE friends CURSOR FOR SELECT f.friend_id FROM friend f WHERE f.user_id = NEW.user_id;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
OPEN friends;

read_loop: LOOP

FETCH friends INTO f_id; -- LA DIFERENCIA

IF done = 1 THEN
      LEAVE read_loop;
    END IF;
-- insertar una notificaion a todos los amigos del usuario disparador del evento

insert into op_event_user_notifications values (null, f_id ,NEW.id, null, false);

END LOOP;


END
//

Antes no me funcionaba, se ejecutaba mas veces de la que debia y en f_id me insertaba null

Código: [Seleccionar]
DROP TRIGGER IF EXISTS trg_ai_op_event_list;
delimiter //
CREATE TRIGGER trg_ai_op_event_list
AFTER INSERT ON op_event_list

for each row
BEGIN
-- agregar si el usuario recibe el tipo de notificaion
DECLARE done INT DEFAULT 0;
DECLARE f_id INT;
DECLARE friends CURSOR FOR SELECT f.friend_id FROM friend f WHERE f.user_id = NEW.user_id;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
OPEN friends;

read_loop: LOOP

IF done = 1 THEN
      LEAVE read_loop;
    END IF;
-- insertar una notificaion a todos los amigos del usuario disparador del evento

FETCH friends INTO f_id; -- LA DIFERENCIA
insert into op_event_user_notifications values (null, f_id ,NEW.id, null, false);


END LOOP;


END
//

Explicando lo que hago:

Este evento se ejecuta cada vez que inserto un registro en la tabla 'op_event_list'
y lo que hace es insertar en la tabla de notificaciones 'op_event_user_notirications'
 un registro para los usuarios amigos del usuario que
ejecuto una tarea y registro un evento determinado.

Lo cierto es que cambie de lugar donde hago el 'FETCH'
realmente no entiendo en que cambian las cosas pero :
- en el primer caso funciona
- en el segundo caso no funciona


Desconectado José Daniel

  • Usuario Junior
  • **
  • Mensajes: 54
  • Puntuación: 1
  • Sexo: Masculino
  • "El conocimiento humano le pertenece al mundo"
    • Ver Perfil
    • Calma en la tormenta [Seienchin]
Re:Triggers en Mysql
« Respuesta #1 : 08 de julio de 2011, 09:27:27 am »
Saludos tierrarara!

Duda: Cuál es el valor de la variable "done" en ambos casos?. No sé como trabaja el manejador, pero es posible que esté obteniendo nuevamente su valor luego del fetch, sino no tendría sentido romper el ciclo con esa variable, quizás es por eso que para el primer ejemplo te funciona y para el segundo no porque se está saliendo inmediatamente del ciclo.

Sugerencia: Falta agregar el "Close Cursor" luego del "End Loop" y antes del "End;".

Indícanos tus observaciones,

Seguimos en contacto.
Twitter: @joseayram

Php + CodeIgniter (HMVC) + Datamapper + Twig + JQuery

https://github.com/joseayram/ci-base

"El conocimiento humano le pertenece al mundo"

Desconectado tierrarara

  • Usuario Junior
  • **
  • Mensajes: 85
  • Puntuación: 3
    • Ver Perfil
    • Rare Earth
Re:Triggers en Mysql
« Respuesta #2 : 08 de julio de 2011, 02:39:11 pm »
La variable "done" cambia de valor a "1" cuando el cursor llega a su fin  o si el resultado del query no devuelve ningún resultado, el cambia el valor automáticamente.  Eso lo tomé del ejemplo de cursores en el manual de mysql

creo que el loop seria mas entendible si encontrara la forma de hacerlo con un while

Código: [Seleccionar]
...
DECLARE done INT DEFAULT 1;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 0;

...
while done // y cambio

end while;

....

nota: es un seudo código de un while en sql, no se como es la sintaxis correcta

de esta forma es mas fácil entender que solo se repite el ciclo mientras el handler
no me cambie el valor de la variable done a "0"

Gracias por lo de cerrar el cursor.








Desconectado José Daniel

  • Usuario Junior
  • **
  • Mensajes: 54
  • Puntuación: 1
  • Sexo: Masculino
  • "El conocimiento humano le pertenece al mundo"
    • Ver Perfil
    • Calma en la tormenta [Seienchin]
Re:Triggers en Mysql
« Respuesta #3 : 09 de julio de 2011, 12:49:02 pm »
Podrías transformarlo a:

Código: [Seleccionar]
DROP TRIGGER IF EXISTS trg_ai_op_event_list;
delimiter //
CREATE TRIGGER trg_ai_op_event_list
AFTER INSERT ON op_event_list


BEGIN
   -- agregar si el usuario recibe el tipo de notificaion
   DECLARE done INT DEFAULT 0;
   DECLARE f_id INT;
   DECLARE friends CURSOR FOR SELECT f.friend_id FROM friend f WHERE f.user_id = NEW.user_id;
   DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
   OPEN friends;

   REPEAT  -- Cambio 1
   
      FETCH friends INTO f_id;
     
      IF NOT done THEN -- Cambio 2
-- insertar una notificaion a todos los amigos del usuario disparador del evento
         insert into op_event_user_notifications values (null, f_id ,NEW.id, null, false);
      END IF;

   UNTIL done END REPEAT; -- Cambio 3

   CLOSE CURSOR friends;   -- Cambio 4

END

Tomado de MySQL Reference Manual 5.0

Saludos!
Twitter: @joseayram

Php + CodeIgniter (HMVC) + Datamapper + Twig + JQuery

https://github.com/joseayram/ci-base

"El conocimiento humano le pertenece al mundo"

PHP de Venezuela

Re:Triggers en Mysql
« Respuesta #3 : 09 de julio de 2011, 12:49:02 pm »

 

PHP de Venezuela on Facebook