Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/55.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中使用游标时,从DECLARE语句调用存储过程_Mysql_Stored Procedures_Cursors - Fatal编程技术网

在MySQL中使用游标时,从DECLARE语句调用存储过程

在MySQL中使用游标时,从DECLARE语句调用存储过程,mysql,stored-procedures,cursors,Mysql,Stored Procedures,Cursors,我尝试在MySQL中使用游标多次调用存储过程。我想在某个临时表中存在我的_id的值时多次调用它,并遍历这些id并连接结果 不管怎么说,我在这个过程中遇到了问题: DECLARE curs CURSOR FOR SELECT something FROM somewhere; 我不想从某处选东西。我想要像这样的东西 DECLARE curs CURSOR FOR CALL storedproc(@an_id); DECLARE语句可以用来调用存储的进程吗?或者它

我尝试在MySQL中使用游标多次调用存储过程。我想在某个临时表中存在我的_id的值时多次调用它,并遍历这些id并连接结果

不管怎么说,我在这个过程中遇到了问题:

  DECLARE curs CURSOR FOR  
    SELECT something FROM somewhere;
我不想从某处选东西。我想要像这样的东西

  DECLARE curs CURSOR FOR  
    CALL storedproc(@an_id);
DECLARE语句可以用来调用存储的进程吗?或者它必须仅与SELECT关联?谷歌搜索一下,恐怕是后者

DECLARE语句可以用来调用存储的进程吗

这是不可能的,文档对此非常清楚

此语句声明一个游标,并将其与一个SELECT语句相关联,SELECT语句检索游标要遍历的行。要稍后提取行,请使用fetch语句。SELECT语句检索到的列数必须与FETCH语句中指定的输出变量数匹配


使用光标需要一些标准的样板代码来包围它

使用游标为表中的每组值调用存储过程需要基本相同的样板文件。您可以从任何地方选择要传递的值,这些值可以是临时表、基表或视图,还可以包括对存储函数的调用,然后使用这些值调用过程

我已经在下面为样板代码编写了一个语法上有效的示例,并用注释解释了每个组件的作用。我最不喜欢的事情莫过于被要求仅仅因为某件事就去做——所以一切都有希望得到解释

您提到使用多个值调用过程,因此本例使用2

请注意,发生在她身上的事件有其特定的顺序。变量必须首先声明,游标必须在其continue处理程序之前声明,循环必须遵循所有这些内容。这给人的印象是,这里有一些相当极端的僵化,但事实并非如此。您可以通过在BEGIN中嵌套其他代码来重置顺序。。。程序体内的端块;例如,如果在循环中需要第二个游标,只需在循环中声明它,在另一个开始中。。。结束


这令人沮丧。这意味着我没有解决办法。我真的很讨厌MySQL!打开一个游标以从临时表读取ID,并在迭代该游标时调用您的过程。但我不能在迭代游标时调用该过程-我只能调用SELECT,因为DECLARE语句中存在限制,正如@PeterWebware在回答中提到的。这不起作用的原因和你不能调用my_程序的原因是一样的,其中。。。订购人。。。LIMIT…,等等。不过,听起来好像你要找的是一个存储函数,它返回一个标量值,可以在游标中重复使用,游标将从表中选择行。你完全正确。实际上,这是一个后续问题。我确实试图直接创建一个关于我的问题的讨论——它被标记为重复,并指向我探索游标。不管是好是坏。。。现在,现在游标没有问题。如果你承诺不再讨厌MySQL,我会看看我是否能为你指明正确的方向。我开始讨厌它了!!我的问题读起来像是起诉……我已经编写了一个标准支持代码的示例,您需要使用游标,特别是在调用另一个proc时。我的联系信息可以在上找到,如果你需要进一步的帮助,在你的转换成为MySQL afficionado。这是惊人的和美妙的。我可以告诉你爱MySQL,你也希望别人也爱。所以,当我开始理解这一点时,首先我注意到从cursor1到val1;的fetchnext出现语法错误?在发布这篇文章之前,我测试了proc的语法,测试的版本在我编写它时是方便的。我再核实一下。您正在运行的版本选择@@version;确切的错误是什么。。。对于要使用near'FETCH的正确语法。。。或者别的什么?请注意,MySQL语法错误往往会告诉您在从左到右的解析中出现了什么意外情况,这意味着错误中提到的内容通常应该在前面加上缺少的内容。。。或者在错误中发现了与预期不同的东西-这意味着实际错误在消息中实际引用的部分,或者就在消息中实际引用的部分之前。已确认,MySQL服务器5.1、5.5、5.6上的有效语法。另请参见具有相同代码的。请注意,Fiddle处理分隔符的方式不同,要求您从下拉列表中选择分隔符,而不是使用DELIMITER client语句,并且只支持//而不是我的标准选择 当然是$$,,但除此之外,小提琴是答案的复制粘贴。这真的很奇怪。我在5.6.28-0ubuntu0.14.04.1-log上,错误消息说语法错误:FROM在此位置不是有效输入我想知道这是否是MySQL工作台的问题?我真的很感激你的建议。
DELIMITER $$

DROP PROCEDURE IF EXISTS `my_proc` $$
CREATE PROCEDURE `my_proc`(arg1 INT) -- 1 input argument; you might not need one
BEGIN

-- from http://stackoverflow.com/questions/35858541/call-a-stored-procedure-from-the-declare-statement-when-using-cursors-in-mysql

-- declare the program variables where we'll hold the values we're sending into the procedure;
-- declare as many of them as there are input arguments to the second procedure,
-- with appropriate data types.

DECLARE val1 INT DEFAULT NULL;
DECLARE val2 INT DEFAULT NULL;

-- we need a boolean variable to tell us when the cursor is out of data

DECLARE done TINYINT DEFAULT FALSE;

-- declare a cursor to select the desired columns from the desired source table1
-- the input argument (which you might or might not need) is used in this example for row selection

DECLARE cursor1 -- cursor1 is an arbitrary label, an identifier for the cursor
 CURSOR FOR
 SELECT t1.c1, 
        t1.c2
   FROM table1 t1
  WHERE c3 = arg1; 

-- this fancy spacing is of course not required; all of this could go on the same line.

-- a cursor that runs out of data throws an exception; we need to catch this.
-- when the NOT FOUND condition fires, "done" -- which defaults to FALSE -- will be set to true,
-- and since this is a CONTINUE handler, execution continues with the next statement.   

DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

-- open the cursor

OPEN cursor1;

my_loop: -- loops have to have an arbitrary label; it's used to leave the loop
LOOP

  -- read the values from the next row that is available in the cursor

  FETCH NEXT FROM cursor1 INTO val1, val2;

  IF done THEN -- this will be true when we are out of rows to read, so we go to the statement after END LOOP.
    LEAVE my_loop; 
  ELSE -- val1 and val2 will be the next values from c1 and c2 in table t1, 
       -- so now we call the procedure with them for this "row"
    CALL the_other_procedure(val1,val2);
    -- maybe do more stuff here
  END IF;
END LOOP;

-- execution continues here when LEAVE my_loop is encountered;
-- you might have more things you want to do here

END $$

DELIMITER ;