如何使用存储过程,游标和for循环获取表值?

时间:2020-11-02 04:30:03

标签: mysql for-loop stored-procedures cursor procedure

我正在构建一个使用游标和循环的存储过程。我了解代码的工作原理,但无法创建条件。我不明白如何调用代码以根据输入参数检查某些单元格中的空值。

我的代码说明: 我正在检查成员是否有任何过期的书。在我称为“ borrowedby”的表中,具有变量“ MemberID”,“ ReturnDate”和“ BookID”。 ReturnDate是书籍归还的日期。输入参数“ memberIDEN”必须等于“ MemberID”,并检查“ ReturnDate”是否为空。如果为null,则打印出memberID和过期的书。

如何创建条件来检查表“ borrowedby”中“ ReturnDate”是否为空?

delimiter //
drop procedure if exists overdueBooks  //

delimiter //
create procedure overdueBooks  (in memberid INT)

begin
declare returnCheck date;
declare finished int default 0;
declare overdueList varchar (100) default "";

declare cursor_data cursor for 
select MemberID 
from borrowedby 
where memberid = MemberID;

declare continue handler for not found set finished = 1;

open cursor_data;

get_members: loop
    fetch cursor_data into overdueList;
    
    if returnCheck is not null 
        then
            leave get_members;
    end if;
end loop get_members;
close cursor_data;
end
//
delimiter ;

2 个答案:

答案 0 :(得分:0)

SP似乎过多。

SELECT *
FROM borrowedby 
WHERE @memberIDEN = MemberID
  AND returnCheck IS NULL

此查询返回指定成员的所有未归还的图书。

答案 1 :(得分:0)

我同意带游标的sp不是行进路线,而是.. sp有很多问题

  1. 您没有在光标选择中获取所有需要的字段
  2. 您已经正确声明了一个处理程序,但是您没有在循环中进行测试,因此您的循环是无限的。
  3. 提取应提取所需的所有列
  4. 一旦找到了过期的书,您就不会对数据进行任何操作。
  5. 您不能满足借款人的逾期和还款组合的情况。

给出的更正SP

DROP TABLE IF EXISTS T;
CREATE TABLE T
(MemberID INT, ReturnDate DATE,BookID INT);

INSERT INTO T VALUES
(1,NULL,1),(1,NULL,3),(2,'2020-11-02',2);

delimiter //

create procedure P  (in memberIDEN INT)

begin
declare returnCheck date;
declare finished int default 0;
declare overdueList varchar (100) default "";

declare cursor_data cursor for 
select MemberID ,RETURNDATE from T where memberIDEN = MemberID;

declare continue handler for not found set finished = 1;

open cursor_data;

get_members: loop
    fetch cursor_data into overdueList,RETURNCHECK;
    
     IF FINISHED = 1 THEN
        LEAVE GET_MEMBERS;
    END IF;
        
    fetch cursor_data into overdueList,RETURNCHECK;
    
    if returnCheck is NULL then
            SELECT OVERDUELIST ' HAS OVERDUE BOOK(S)';
    end if;
end loop get_members;
close cursor_data;
end //
delimiter ;