2009-10-29 94 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"; 
}