MySQL Call in loop - PullRequest
       16

MySQL Call in loop

1 голос
/ 04 февраля 2012

Я создал хранимую процедуру, которая выглядит следующим образом:

DELIMITER €€
CREATE PROCEDURE `GetAllNonprocessedSMSes`()
   BEGIN
      DECLARE smsid INT(10);
      DECLARE finish BOOLEAN;

      DECLARE id_cur CURSOR FOR
         SELECT id FROM (
            SELECT
               MIN(id) as id,
               MIN(UDH) as udh,
               MIN(LENGTH(TextDecoded)) as txtlen,
               MAX(ReceivingDateTime)-DATE_ADD(MIN(ReceivingDateTime), INTERVAL 3 MINUTE) AS rcvtimeout
            FROM inbox
            WHERE
               Processed='false'
            GROUP BY
               IF(UDH='',id,SUBSTR(UDH,1,10))
            HAVING
               rcvtimeout>0
               OR udh=''
               OR txtlen<156
         ) AS baseview
         ORDER BY id;

      DECLARE CONTINUE HANDLER FOR NOT FOUND SET finish = TRUE;
      OPEN id_cur;

      the_loop : LOOP
         FETCH id_cur INTO smsid;
         CALL GetSMS(smsid);

         IF finish THEN
            CLOSE id_cur;
            LEAVE the_loop;
     END IF;
      END LOOP the_loop;
   END €€
DELIMITER ;

Я знаю, что курсор выбирает более одной строки, но когда я вызываю процедуру, он возвращает только одну запись, но при запуске он возвращает только первую запись.
Как я могу это исправить?

РЕДАКТИРОВАТЬ
Хранимая процедура GetSMS выглядит как

CREATE PROCEDURE `GetSMS`(IN smsid int(10))
   BEGIN
      DECLARE smsudh TEXT;
      SELECT `UDH` INTO smsudh FROM `inbox` WHERE `ID`=smsid;
      IF (STRCMP(smsudh, '') < 1) THEN
         SELECT * FROM `inbox` WHERE `ID`=smsid;
      ELSE
         SELECT * FROM `inbox` WHERE `UDH` LIKE CONCAT(LEFT(smsudh, (LENGTH(smsudh)-2)), "%") GROUP BY `ID` ORDER BY `UDH`;
      END IF;
   END €€
DELIMITER ;

Ответы [ 3 ]

0 голосов
/ 05 февраля 2012

Я действительно не вижу, что вы пытаетесь выполнить, но здесь есть несколько проблем.

1) Ваше условие завершения неверно.

  DECLARE finish BOOLEAN DEFAULT 0; # <- set up initial conditions
  ...
  the_loop : LOOP
     FETCH id_cur INTO smsid;

     IF finish THEN
        CLOSE id_cur;
        LEAVE the_loop;
     END IF

     CALL GetSMS(smsid);  # <- move the call to GetSMS after the finish, or it will be called with an invalid record.

2)Вызов GetSMS возвращает выбор для каждого вызова.Эти выборы будут возвращены клиенту отдельно.Вам нужно найти способ объединить их в одну таблицу.

0 голосов
/ 05 февраля 2012

Можете ли вы тогда выяснить, есть ли способы создания GetSMS? Процедура как один оператор SELECT, поэтому я могу создать его как INSERT INTO tmptable SELECT ... - The87Boy 3 минуты назад

# положить в ПРОЦЕДУРУ GetAllNonprocessedSMSes

DROP TABLE IF EXISTS TempTable;
CREATE TABLE TempTable LIKE `inbox`; 

# затем в GetSMS

  IF (STRCMP(smsudh, '') < 1) THEN
     INSERT INTO TempTable SELECT * FROM `inbox` WHERE `ID`=smsid;
  ELSE
     INSERT INTO TempTable SELECT * FROM `inbox` WHERE `UDH` LIKE CONCAT(LEFT(smsudh, (LENGTH(smsudh)-2)), "%") GROUP BY `ID` ORDER BY `UDH`;
  END IF;

Возможно, вы захотите установить блокировку вокруг TempTable, чтобы не запускать две копии процедуры одновременно.

0 голосов
/ 04 февраля 2012

Не уверен, что происходит в вашей функции GetSMS, но вы когда-нибудь пытались обернуть ее как

select 
      GetSMS( baseQuery.ID )
   from
      ( your current query ) baseQuery

Я не знаю, что может вернуть GetSMS, если она возвращает что-то, даже1, true, "", тогда вы просто игнорируете результаты результата запроса, но каждый квалифицированный идентификатор из вашего запроса будет передан в качестве аргумента функции.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...