0

I have a situation in which I would like to iterate through a "schedPayments" table that stores a schedule of payments corresponding with a client in the "client" table. The client table also contains a "status" column at the moment holds a 0 for "Past Due" and a 1 for "Current". When the balance from the client table is greater than the supposed balance from the schedPayments table AND today's date is later than the date the payment was scheduled for, the status column in the clients table should be set to 0.

I may be completely off the wall with my solution, but I keep getting Error Code: 1329. No Data - zero rows fetched, selected or processed. The MySQL Workbench lacks some major debugging capabilities that I wish it had. The documentation also doesn't quite cover what I need either in this situation.

CREATE PROCEDURE `project`.`status_update` ()
BEGIN  
DECLARE balance DECIMAL(20) DEFAULT 0;
DECLARE cID INT(10) DEFAULT 0;
DECLARE currentID INT(10) DEFAULT 0;
DECLARE supposedBal DECIMAL(20) DEFAULT 0;
DECLARE payDate DATE;
DECLARE cur1 CURSOR FOR SELECT ClientID,SupposedBalance,Date FROM project.schedpayments;

OPEN cur1;

status_loop: LOOP
    FETCH cur1 INTO cID, supposedBal, payDate;
    BLOCK2: BEGIN 
        DECLARE cur2 CURSOR FOR SELECT balance FROM project.client WHERE ID=cID;
        OPEN cur2;  
        FETCH cur2 INTO balance;
        IF currentID > cID THEN
            SET currentID = cID;
            IF (CURDATE() > payDate) AND (supposedBal < balance) THEN
                UPDATE feeagree SET Status=0 WHERE ID=cID;
            END IF;
            CLOSE Cur2;

        END IF;
    END BLOCK2;

END LOOP;
CLOSE cur1;
END $$

You can see the remnants of how I had enclosed the entire procedure in a block and that only resulted in the compiler thinking the first block ended with END BLOCK2; and that resulted in an Error Code 1325. Cursor is already open.

I am definitely making this more complicated than necessary, so any help would be much appreciated. The only way I learn this stuff is trial by fire, and it is super hot today.

4

2 回答 2

0
...

DECLARE done TINYINT DEFAULT FALSE;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET DONE = true;
OPEN cur1;

status_loop: LOOP
    FETCH cur1 INTO cID, supposedBal, payDate;
    IF DONE = true THEN LEAVE status_loop; END IF;

...

SET DONE = false;
END LOOP;

最后的 SET DONE = false 会重置 DONE,以防内部块中的任何内容导致它设置为 TRUE;

于 2013-06-21T01:46:16.397 回答
0

似乎您不需要所有这些游标,您可以通过一个UPDATE语句来实现您的目标。

如果没有看到您的表结构和示例数据,很难准确,但您的 SP 的更简洁版本可能看起来像这样

CREATE PROCEDURE status_update()
  UPDATE feeagree 
     SET Status = 0 
   WHERE ID IN
  (
     SELECT p.cID
       FROM schedpayments p JOIN client c
         ON p.cID = p.ID
      WHERE p.Date < CURDATE() 
        AND p.SupposedBalance < c.balance
      GROUP BY p.cID
  );
于 2013-06-14T07:42:37.850 回答