SQLinfo.ru - Все о MySQL

Форум пользователей MySQL

Задавайте вопросы, мы ответим

Вы не зашли.

#1 19.08.2011 12:40:26

Receptor
Участник
Зарегистрирован: 19.08.2011
Сообщений: 6

Вызова 1 и тойже процедуры из события с разными параметрами

Необходимо вызывать 1 процедуру с разными входными значениями в определенные интервалы времени. События, как я понимаю, могут обеспечить вызов процедур в определенные промежутки времени. При вызове процедуры в нее передается имя таблицы. Но на деле событие вызывает процедуру 1 раз,т.е изменения затрагивают только таблицу указанную в первом вызове, дальше же ничего не происходит. Помогите разобраться.

Код события:


CREATE
    DEFINER = 'maksim'@'1.1.1.1'
EVENT delete_premium_for_time
    ON SCHEDULE EVERY '30' MINUTE
    STARTS '2011-08-19 15:06:18'
    ON COMPLETION PRESERVE
    DO
BEGIN
  CALL delete_premium_for_time('table1');
  CALL delete_premium_for_time('table2');
  CALL delete_premium_for_time('table3');
  CALL delete_premium_for_time('table4');
  CALL delete_premium_for_time('table5');
  CALL delete_premium_for_time('table6');
  CALL delete_premium_for_time('table7');
END

Отредактированно Receptor (22.08.2011 06:35:43)

Неактивен

 

#2 19.08.2011 15:33:09

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5842

Re: Вызова 1 и тойже процедуры из события с разными параметрами

Предположу, что это не код события, а код, с помощью которого вы создавали событие без использования delimiter. В этом случае событие как раз включает в себя только первый вызов процедуры.
Проверить какое событие на самом деле у вас определено можно через information_schema.

Неактивен

 

#3 22.08.2011 07:27:07

Receptor
Участник
Зарегистрирован: 19.08.2011
Сообщений: 6

Re: Вызова 1 и тойже процедуры из события с разными параметрами

т.е. если использовать подобный код:


DELIMITER //
CREATE
    DEFINER = 'maksim'@'1.1.1.1'
EVENT delete_premium_for_time
    ON SCHEDULE EVERY '30' MINUTE
    STARTS '2011-08-19 15:06:18'
    ON COMPLETION PRESERVE
    DO
BEGIN
  CALL delete_premium_for_time('table1');
  CALL delete_premium_for_time('table2');
END //
DELIMITER ;


то все должно сработать нормально? пробовал создать событие подобным образом, но проблема не разрешилась.

Попробовал для эксперемента такой код внутри события без использования delimeter:

BEGIN
  CALL delete_premium_for_time('table1');
  UPDATE table1 SET value=2 WHERE id=3;
  CALL delete_premium_for_time('table2');
END
 


Работает, т.е. после первого вызова процедуры дальше UPDATE тоже сработал. Следующий вызов процедуры снова не работает. Может быть дело именно в CALL?

Отредактированно Receptor (22.08.2011 09:11:55)

Неактивен

 

#4 22.08.2011 11:39:05

evgeny
Гуру
Зарегистрирован: 04.05.2009
Сообщений: 335

Re: Вызова 1 и тойже процедуры из события с разными параметрами

Содержания delete_premium_for_time в студию.

Неактивен

 

#5 22.08.2011 13:40:13

Receptor
Участник
Зарегистрирован: 19.08.2011
Сообщений: 6

Re: Вызова 1 и тойже процедуры из события с разными параметрами

delete_premium_for_time:

CREATE DEFINER = 'user_name'@'1.1.1.1'
PROCEDURE delete_premium_for_time(IN t_name VARCHAR(255))
BEGIN
  SET @stmt = concat("UPDATE ", t_name," AS o
  LEFT JOIN city AS c
  ON (c.id = o.city_id)
  SET
    o.ispremium = 0
  WHERE
    o.ispremium IN (1, 2)
    AND c.premium_visible = 1
    AND o.pay_date <= current_timestamp - c.premium_live_time * 86400;"
);
    PREPARE stmt FROM @stmt;
    EXECUTE stmt;
    DEALLOCATE PREPARE stmt;

  BEGIN
    DROP VIEW IF EXISTS delete_premium_for_time;
    SET @stmt_text = concat("CREATE VIEW delete_premium_for_time AS SELECT c.id
         , o.re_type
         , c.offer_premium
         , count(if(o.ispremium = 1, 1, NULL)) AS count_prem
         , count(if(o.ispremium = 2, 1, NULL)) AS count_prem_out
    FROM
      "
, t_name, " AS o
    LEFT JOIN city AS c
    ON (c.id = o.city_id)
    WHERE
      c.premium_visible = 1
      AND o.ispremium IN (1, 2)
    GROUP BY
      o.city_id
    , o.re_type"
);
    PREPARE stmt FROM @stmt_text;
    EXECUTE stmt;
    DEALLOCATE PREPARE stmt;
  END;

  BEGIN
    DECLARE lim            INT DEFAULT 0;
    DECLARE done           INT DEFAULT 0;
    DECLARE id             INT DEFAULT 0;
    DECLARE re_type        INT DEFAULT 0;
    DECLARE offer_premium  INT DEFAULT 0;
    DECLARE count_prem     INT DEFAULT 0;
    DECLARE count_prem_out INT DEFAULT 0;
    DECLARE cur1 CURSOR FOR SELECT *
                            FROM
                              delete_premium_for_time;
    DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1;

    OPEN cur1;
    WHILE done = 0
    DO
      FETCH cur1 INTO id, re_type, offer_premium, count_prem, count_prem_out;
      IF (count_prem < offer_premium) AND (count_prem_out > 0) THEN
        SET lim = offer_premium - count_prem;
        SET @sql = concat('UPDATE ', t_name, ' SET ispremium = 1 WHERE ispremium = 2 and re_type = ', re_type, ' and city_id = ', id, ' ORDER BY pay_date DESC LIMIT ', lim);
        PREPARE stmt FROM @sql;
        EXECUTE stmt;
        DEALLOCATE PREPARE stmt;
      END IF;
    END WHILE;
    CLOSE cur1;
  END;
  DROP VIEW delete_premium_for_time;
END


Все-таки было установлено, что работает и 2 вызов (небольшие поправки внес). Но не работает выражение внутри курсора во 2 и далее вызове процедуры. Предполагаю, что из-за использования view....

Отредактированно Receptor (22.08.2011 13:54:58)

Неактивен

 

#6 22.08.2011 19:30:59

evgeny
Гуру
Зарегистрирован: 04.05.2009
Сообщений: 335

Re: Вызова 1 и тойже процедуры из события с разными параметрами

Никогда не запускал одну и тоже процедуру несколько раз ... Может в переменных остаются значения ?  Попробуй обнулить переменные, в конце процедуры.

Неактивен

 

#7 25.08.2011 14:33:11

Receptor
Участник
Зарегистрирован: 19.08.2011
Сообщений: 6

Re: Вызова 1 и тойже процедуры из события с разными параметрами

Проблему разрешил, оказывается, что при создании VIEW, если какое-то поле содержит count, то потом использовав его в курсоре получится не то, что ожидаешь. Будут не пойми какие значения. Проблема решилась следующим образом:

вместо

count(if(o.ispremium = 1, 1, NULL)) AS count_prem

нужно писать это
CONVERT(count(if(o.ispremium = 1, 1, NULL)),UNSIGNED) AS count_prem


Значит проблема в типах значений была. Интересно, если запустить процедуру с параметром, то все срабатывало, однако, если сделать это через событие, то проблема появлялась.

Отредактированно Receptor (25.08.2011 14:33:57)

Неактивен

 

Board footer

Работает на PunBB
© Copyright 2002–2008 Rickard Andersson