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

bd96500e110b49cbb3cd949968f18be7.png

I am trying to use a cursor in MySQL to call a stored procedure many times. I want to call it as many times as a value for my_id exists in some temporary table, and iterate through those ids and concatenate the results.

Anyway, I'm having trouble with this part of the process:

DECLARE curs CURSOR FOR

SELECT something FROM somewhere;

I don't want to select something from somewhere. I want something like

DECLARE curs CURSOR FOR

CALL storedproc(@an_id);

Can the DECLARE statement be used to call a stored proc? Or does it have to be associated with a SELECT only? Googling around, I'm afraid that the latter is the case.

解决方案

Using a cursor requires some standard boilerplate code to surround it.

Using a cursor to call a stored procedure for each set of values from the table requires essentially the same boilerplate. You SELECT the values you want to pass, from wherever you're getting them (which could be a temporary table, base table, or view, and can include calls to stored functions) and then call the procedure with those values.

I've written an syntactically valid example of that boilerplate code, below, with comments to explain what each component is doing. There are few things I dislike more than being asked to just do something "just because" -- so everything is (hopefully) explained.

You mentioned calling the procedure with multiple values, so this example uses 2.

Note that there events that happen her are in a specific order for a reason. Variables have to be declared first, cursors have to be declared before their continue handlers, and loops have to follow all of those things. This gives an impression that there's some fairly extreme inflexibility, here, but that's not really the case. You can reset the ordering by nesting additional code inside BEGIN ... END blocks within the procedure body; for example, if you needed a second cursor inside the loop, you'd just declare it inside the loop, inside another BEGIN ... END.

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 ;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值