2009-10-29 101 views
0

我正在尝试编写一个过程,它将触发相同的select查询,直到结果数大于0.如果“interval 2 hour”返回0个记录,则“interval 4 hour “标准,并且如果仍没有记录被提取,则应在where子句中使用lastupdate> current_date()。直到在存储过程中循环

这些是过程中使用的2个基本查询。

select sql_calc_found_rows id from sometable where lastupdate > date_sub(now(), interval 2 hour) limit 10; 

select found_rows(); 
+--------------+ 
| found_rows() | 
+--------------+ 
|   41 | 
+--------------+ 

以下步骤是否正确?这是写SP的正确方法吗?我如何在PHP代码中使用结果?

delimiter $$ 
create procedure mytest3() 
begin 

    declare myvar int; 

select sql_calc_found_rows id 
    from sometable 
    where lastupdate > date_sub(now(), interval 2 hour) 
    limit 10; 

select found_rows() into myvar; 

if (myvar > 0) 
    then select 'Found in 2 hours'; 
else 
    select sql_calc_found_rows id 
    from sometable 
    where lastupdate > date_sub(now(), interval 4 hour) 
    limit 10; 

select found_rows() into myvar; 

if (myvar > 0) 
    then select 'Found in 4 hours'; 
else 
    select sql_calc_found_rows id 
    from sometable 
    where lastupdate > current_date() 
    limit 10; 
end if; 
end if; 
end$$ 
+1

为什么你想要做这样的事情?你能描述一下这个场景吗? – shahkalpesh 2009-10-29 06:44:38

+1

你想看看使用WHILE循环:http://dev.mysql.com/doc/refman/5.0/en/while-statement.html – 2009-10-29 06:44:55

+0

为什么?航空公司飞行计划;试图在2小时的时间段内找到航班,如果在2小时的时间段内没有任何时间段,则会在4小时后回落,如果在4小时的时间段内没有任何时间,则会在整天后退。作为一个“例如”,当然...... – 2009-11-07 15:27:26

回答

4

根据您的情况,最好在数据库上设置触发器(http://dev.mysql.com/doc/refman/5.0/en/triggers.html)。这样,只有在相关数据发生变化时,才可以执行任何必要的工作/重新计算,而不会在数据库中没有发生任何更改时通过轮询持续不必要地繁忙服务器。

0

从MySQL文档:

CREATE PROCEDURE dowhile() 
BEGIN 
    DECLARE v1 INT DEFAULT 5; 

    WHILE v1 > 0 DO 
    ... 
    SET v1 = v1 - 1; 
    END WHILE; 
END 
0

PHP页面将用户触发,让你不得不结果保存到数据库中,直到有人打开该页面,该页面显示的结果。

您可以使用PHP cronjob代替在数据库中使用无限循环。

2

这是我第一次尝试在StackOverflow上发布答案。希望它有帮助..

我已经写了一个测试程序,使用我的本地MySQL数据库。它被设置为运行10秒,如果没有记录,则返回空结果集。如果一行在它运行的十秒内插入,它将退出循环并返回新的结果。

睡眠功能可以防止程序在运行时通过只运行Select Count(*)每秒一次地进食太多的CPU。您可以将其设置为您想要的任何间隔。

虽然这个程序运作良好,但我必须同意natevw使用Triggers来代替。

DELIMITER $$ 

CREATE PROCEDURE sp_TestQueryResultsTimeout() 
BEGIN 


    DECLARE v_interval, ct, v_time INT; 

    /* This will keep track of how much time has passed*/ 
    SET v_interval = 0; 

    /* This is used for comparing the rowcount*/ 
    SET ct = 0; 

    /* This is used to keep the procedure from returning the Sleep functions results' 
     This could also be used to keep a more accurate count of the amount of Sleep time has passed by adding the results of the sleep function to it on every iteration*/ 
    SET v_time = 0; 

    /* This while statement should run for slightly longer than ten seconds 
     The amount of extra time will begin to add up depending on how long the select count (*) takes 
     and how many iterations you want to make'*/ 

    WHILE v_interval < 10 DO 

    /*Get the count from your table*/ 
     SET ct = (SELECT count(*) FROM tbUsers); 

    /*If the count is greater than 0, exit the while by satisfying the condition*/ 
    if (ct > 0) then 
    SET v_interval = 10; 
    else 
    /*If the count is less than 0, sleep for 1 second*/ 
     SET v_time = (SELECT SLEEP(1)); 
    end if; 

     /*Increment*/ 
     SET v_interval = v_interval + 1; 
    END WHILE; 

    SELECT * FROM tbUsers; 

END$$ 

DELIMITER ; 
5

它发生,我认为当你要求在标题和文本的身体的循环,你真正要做的是获得“在过去的X修改的行列表小时”,用它返回一些(非空)行最小X ...

这里是实现这一目标的方式之一:

delimiter $$ 
create procedure recently_modified_rows() 
begin 

    declare tablelastupdate int; -- how many hours ago table was last updated. 
    declare showperiod datetime; -- what time interval to show 
    declare showtext text;  -- text describing time interval 

    select hour(timediff(now(), max(lastupdate))) into tablelastupdate 
    from sometable; 

    if(tablelastupdate < 2) 
    set showperiod = time_sub(now(), interval 2 hours); 
    set showtext = "modified in the last 2 hours"; 
    elseif (tablelastupdate < 4) 
    set showperiod = time_sub(now(), interval 4 hours); 
    set showtext = "modified in the last 4 hours"; 
    else 
    set showperiod = current_date(); 
    set showtext = "modified today"; 
    end if 

    select sql_calc_found_rows id, 
     showtext description 
    from sometable 
    where lastupdate > showperiod 
    limit 10; 

end$$ 

,并把它从PHP拨打:

$query = mysql_query("call recently_modified_rows()") or die(mysql_error()); 
$numrows = mysql_numrows($query); 

if ($numrows != 0) 
{ 
    /* print out what time interval we used */ 
    $description = mysql_result($query, 0, 'description'); 
    echo "Found $numrows rows $description"; 

    /* print out the rows */ 
    while ($row = mysql_fetch_array($query)) 
    { 
     echo "Id: {$row['id']}"; 
    } 

} 
else 
{ 
    /* happens only if there were no records modified in any of the three versions */ 
    echo "no records were modified in the last 2 hours, 4 hours, or today"; 
}