Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/78.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 如何在存储过程中创建变量游标?_Mysql_Sql_Stored Procedures_Cursor - Fatal编程技术网

Mysql 如何在存储过程中创建变量游标?

Mysql 如何在存储过程中创建变量游标?,mysql,sql,stored-procedures,cursor,Mysql,Sql,Stored Procedures,Cursor,我正在编写一个处理MySQL表的过程,该表的名称取决于日期,格式为cdr\u 20131108。我的程序应该能够从任何给定日期的表执行一些操作 所有这些表都具有相同的结构,并包含一个时间字段。对于每一行,我需要检查前一小时有多少行符合某些条件。据我所知,我需要一个游标来查找当前行的时间以及更多的数据,然后准备并执行一个查询,从中我将找到我的结果 在伪代码中: DELIMITER $$ CREATE DEFINER=`root`@`localhost` PROCEDURE `myproc`()

我正在编写一个处理MySQL表的过程,该表的名称取决于日期,格式为
cdr\u 20131108
。我的程序应该能够从任何给定日期的表执行一些操作

所有这些表都具有相同的结构,并包含一个
时间
字段。对于每一行,我需要检查前一小时有多少行符合某些条件。据我所知,我需要一个游标来查找当前行的时间以及更多的数据,然后准备并执行一个查询,从中我将找到我的结果

在伪代码中:

DELIMITER $$

CREATE DEFINER=`root`@`localhost` PROCEDURE `myproc`()
BEGIN

DECLARE all necessary variables to save the data returned by the cursor    

DECLARE c1 cursor for
    select required fields
    from cdr_20131103
    where some criteria;

DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET _done = TRUE;

set @tablename := concat('rm_cdrs',date_format(curdate(),'%Y%m%d'));
set @entries := 0;

open c1;
c1_loop: loop
    fetch c1 into my variables;
    if `_done` then leave c1_loop; end if;      
    set @q := concat('... my query is prepared here: select count(*) into @variable (
                        select in which i look for rows that meet my criteria that 
                        happened less tan an hour before the one in the cursor)');

    PREPARE stmt FROM @q;    EXECUTE stmt; DEALLOCATE PREPARE stmt;

  if some criteria is met then do some stuff...

end loop c1_loop;
close c1;

END
因此,当我需要在不调整代码的情况下检查今天的表时,我的问题就出现了,因为MySQL不允许我在这里使用变量:

DECLARE c1 cursor for
select required fields
from cdr_20131103
where some criteria;
我尝试创建一个过程,在这里用正确的表名生成所需的过程,但MySQL不允许我删除或更改存储例程中的过程

在这种情况下有什么解决办法吗

  • 在这种情况下,我可以避免使用光标吗

  • 如前所述,我是否应该手动执行游标的任务

  • 此过程可能会使用cron定期调用。我是否应该编写一些Java/C/PHP应用程序,在删除旧程序后创建并调用正确的程序

多谢各位


编辑:

@Sebas声明,可以使用单个insert select语句执行此操作。虽然他的回答中的观点技巧很有魅力,但我还是想尝试从中学习。我将添加更多信息:

选择感兴趣的列并使用where子句过滤数据时,
cdr_20131103
如下所示:

+---------+----------------+--------+
| user_ID | destination_ID |  time  |
+---------+----------------+--------+
|       2 |             56 | 110312 |
|       4 |             53 | 110513 |
|       2 |             56 | 110821 |
|       2 |             56 | 113212 | *
|       2 |             56 | 123001 |
+---------+----------------+--------+
我需要找出同一用户ID在一小时内访问同一目的地ID至少3次的时间。因此,带有
*
的行应该与now()字段一起插入到另一个表中

我的线性思维告诉我应该一行一行地处理,计算初始时间(
时间间隔1小时
),选择在该时间间隔内具有相同用户ID和目标ID的行,对它们进行计数,并最终将它们插入到另一个表中

在SQL中有更好的方法来实现这一点吗


非常感谢!

我想你可以用一个
选择insert
SQL来做你想做的一切。研究类似的事情(假设
tabletoinsert
,假设
time
的列类型是
VARCHAR

但如果你真的需要光标,你也可以使用肮脏的技巧:

1-在另一个存储过程中动态创建视图

SET @dyn_sql = CONCAT('CREATE OR REPLACE VIEW `v_yourview` AS ', 
                               SELECT required fields
                               FROM cdr_', date_format(curdate(),'%Y%m%d'), ' WHERE some criteria;');

PREPARE stmt_dyn_view FROM @dyn_sql;
EXECUTE stmt_dyn_view;
DEALLOCATE PREPARE stmt_dyn_view;
2-在主程序的光标中使用它:

DECLARE c1 cursor for
    select required fields
    from v_yourview
    where some criteria;

我们可能会找到一个更简单的解决方法。
如果满足一些条件,那么做一些事情…
什么事情?那么insert/select呢?通过一个全局选择,包括游标的计数和查询,您可以在任何符合您条件的表中插入数据。一次查询:当然可以。有时mysql是有限的,但我认为我们可以k它是您的系统h24还是h12?另外,
time
的列类型是什么?您需要在另一个表中插入
time
值,还是只是
NOW()
?非常感谢!我使用视图进行了工作。这是否有效?使用视图为我节省了大量的行数,并减少了我在查询中需要检查的条件数。是的,视图与基础查询一样有效。它不增加任何存储要求,只是
创建视图授权
(或者,
CREATE TABLE
就足够了?)。您好@Sebas!感谢您提供的宝贵帮助。我已经尝试了一段时间。虽然这是一种在自然时间(例如11:00-11:59)查找条目的非常简洁的方法,但我认为它在其他情况下(例如11:30-12:20)不会检测到它。我已经尝试使用
have count(*)来实现这一点>=3和timediff(max(time(mytime)),min(time(mytime)))我不太清楚。为什么不使用SUBSTR版本?
DECLARE c1 cursor for
    select required fields
    from v_yourview
    where some criteria;