我正在尝试编写一个过程,该过程将触发相同的选择查询,直到结果数大于0.如果“间隔2小时”返回0记录,则应使用“间隔4小时”标准,如果那时仍然没有记录 lastupdate> current_date()应该在where子句中使用。
这些是程序中使用的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$$
答案 0 :(得分: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";
}
答案 1 :(得分:4)
根据您的具体情况,最好在数据库上设置触发器(http://dev.mysql.com/doc/refman/5.0/en/triggers.html)。这使您可以仅在相关数据更改时执行任何必要的工作/重新计算,而不是通过持续轮询使服务器不必要地繁忙,即使数据库中没有任何更改也是如此。
答案 2 :(得分:2)
这是我第一次尝试在StackOverflow上发布答案。希望它有用..
我在下面使用我的本地MySQL数据库编写了一个测试程序。如果没有记录,它将设置为运行10整秒并返回空结果集。如果在它运行的十秒内插入一行,它将退出循环并返回新结果。
睡眠功能用于防止程序在运行时因每秒只运行一次选择计数(*)而占用太多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 ;
答案 3 :(得分:0)
来自MySQL文档:
CREATE PROCEDURE dowhile()
BEGIN
DECLARE v1 INT DEFAULT 5;
WHILE v1 > 0 DO
...
SET v1 = v1 - 1;
END WHILE;
END
答案 4 :(得分:0)
PHP页面将由用户触发,因此您必须将结果保存到数据库中,直到有人打开该页面(显示结果)。
您可以使用PHP cronjob,而不是在数据库中使用无限循环。