MySQL调用循环

时间:2012-02-04 19:18:24

标签: mysql stored-procedures call

我创建了一个存储过程,如下所示:

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 ;

我知道游标选择了多行,但是当我调用Procedure时它只返回一个条目,但是当它被运行时它只返回第一个条目。
我该如何解决这个问题?

修改
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 :(得分:0)

不确定您的函数GetSMS中发生了什么,但您是否曾尝试将其包装起来,如

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

我不知道GetSMS可能会返回什么,只要它返回SOMETHING,即使是1,true,“”,那么您只需忽略查询结果的结果,但查询中的每个限定ID都将作为函数的参数。

答案 1 :(得分:0)

我真的看不出你想要完成什么,但这里有一些问题。

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的调用会返回每个调用的选择。这些选择将单独返回给客户。你需要想办法将它们连接到一个表中。

答案 2 :(得分:0)

  

您是否可以确定是否有任何方法可以创建GetSMS   作为一个SELECT语句的过程,所以我可以像INSERT INTO一样创建它   tmptable SELECT ... - The87Boy 3分钟前

#put into PROCEDURE 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,以便不会同时运行该过程的两个副本。