简体   繁体   中英

'select into' statement not working in mysql store procedure with cursor

Here is the issue: temprequest is the table where i fetch rows from. I look up the deliverableId column of deliverable table based on the temprequest table while fetching. therefore i use a select into statement. but the variable where I put the looked up value is only working for the first row fetched.

The 'Begin end' block:

DECLARE no_more_rows BOOLEAN;
DECLARE nr_rows INT DEFAULT 0;  
DECLARE loop_cntr INT DEFAULT 0;

declare delId int;

declare vtname varchar(200);
declare tversion varchar(200);
declare custId int;
declare prod varchar(200);

DECLARE c_temp CURSOR FOR select tname, version,BuID,BuprodName from temprequest;
SET no_more_rows = False;

OPEN c_temp;
select FOUND_ROWS() into nr_rows;

the_loop:LOOP
    FETCH c_temp into vtname,tversion,custId, prod;
    IF no_more_rows THEN            
        LEAVE the_loop;
    END IF;
    -- statements for each request record
    Set delId= (SELECT deliverableId  
                FROM deliverable 
                WHERE deliverable.Product_prodName =vtname AND deliverable.version = tversion);
    INSERT INTO request VALUES (delId, custId, prod);               
    SET loop_cntr = loop_cntr + 1;

END LOOP the_loop;
CLOSE c_temp;

To accomplish the same without cursor use (UPDATED ):

INSERT INTO request 
SELECT 
    deliverable.deliverableId   as delId,
    qwe.BuID            as custId,
    qwe.BuprodName          as prod

FROM deliverable 
inner join 
(select tname, version, BuID,BuprodName 
from temprequest) 
    as qwe (tname, version, BuID,BuprodName) 
        on deliverable.Product_prodName = qwe.vtname 
       AND deliverable.version = qwe.tversion

I've just realised that BuID and BuprodName are constants here and not used anywhere besides insert statement.

The no_more_rows variable gets set to true if any query within the cursor doesn't fetch any result. In your case if the following query doesn't fetch any result, even in that case no_more_rows will evaluated as true .

SELECT deliverableId  
FROM deliverable 
WHERE deliverable.Product_prodName =vtname AND deliverable.version = tversion

Solution for this is to set no_more_rows to false at the end of the cursor, so that even if it evaluates to true during cursor execution, it will be reset and will be exited only when there are no rows returned by the cursor query.

he_loop:LOOP
    FETCH c_temp into vtname,tversion,custId, prod;
    IF no_more_rows THEN            
        LEAVE the_loop;
    END IF;
    -- statements for each request record
    Set delId= (SELECT deliverableId  
                FROM deliverable 
                WHERE deliverable.Product_prodName =vtname AND deliverable.version = tversion);
    INSERT INTO request VALUES (delId, custId, prod);               
    SET loop_cntr = loop_cntr + 1;
    SET no_more_row = false
END LOOP the_loop;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM