Вывод процедуры PL/SQL

#sql #plsql

Вопрос:

У меня возникли проблемы с корректным отображением результатов моей процедуры. Когда я выполняю созданную мной процедуру. Вывод должен быть «FALSE», так как DonorID: 303 имеет idStatus = 20 и Paymonths = 0. Тем не менее, я становлюсь «ПРАВДИВЫМ». Может кто-нибудь, пожалуйста, помочь?

 CREATE OR replace PROCEDURE ddpay_sp (donorid IN NUMBER,
                                      completed_pledge OUT BOOLEAN)
IS
  CURSOR donor_cur IS
    SELECT idstatus,
           paymonths
    FROM   dd_pledge
    WHERE  iddonor = donorid;

p_idstatus  NUMBER(2);
p_paymonths NUMBER(3);
BEGIN
  OPEN donor_cur;
  LOOP
    FETCH donor_cur
    INTO  p_idstatus,
          p_paymonths;
    EXIT WHEN donor_cur%NOTFOUND;
    IF p_idstatus = 20 AND p_paymonths = 0 THEN
      completed_pledge := FALSE;
    ELSE
      completed_pledge := TRUE;
      EXIT;
    END IF;
  END LOOP;
  CLOSE donor_cur;
END ddpay_sp;

DECLARE
  status BOOLEAN;
BEGIN
  ddpay_sp(303, status);
  IF status = TRUE THEN
    dbms_output.put_line('TRUE');
  ELSE
    dbms_output.put_line('FALSE');
  END IF;
END;
 

Комментарии:

1. Пожалуйста, предоставьте примеры данных, желаемые результаты и четкое объяснение того, что должен делать код.

2. «… Донор: 303 имеет idStatus = 20». Действительно? Откуда мы это знаем?

Ответ №1:

Если у вас в таблице несколько строк , которые совпадают iddonor = donorid , Oracle будет перебирать их до тех пор, пока не найдет ту, которая не соответствует вашему p_idstatus = 20 AND p_paymonths = 0 условию, а затем выйдет из цикла с true , он вернет «ЛОЖЬ» только в том случае, если все они совпадают по второму условию. Если у вас нет совпадающих строк iddonor = donorid , то ваш чек покажет «ЛОЖЬ».

Вам нужно четко понимать, что должно происходить, когда есть несколько строк, в dd_pledge которых есть входное значение iddonor. Например, если вы хотите, чтобы оно возвращалось false , если есть какие-либо совпадающие строки, idstatus=20 and paymonths=0 то вы могли бы вместо этого выполнить цикл exit при этом условии:

 CREATE OR replace PROCEDURE ddpay_sp (donorid IN NUMBER,
                                      completed_pledge OUT BOOLEAN)
IS
  CURSOR donor_cur IS
    SELECT idstatus,
           paymonths
    FROM   dd_pledge
    WHERE  iddonor = donorid;

p_idstatus  NUMBER(2);
p_paymonths NUMBER(3);
BEGIN
  
  OPEN donor_cur;
  LOOP
    FETCH donor_cur
    INTO  p_idstatus,
          p_paymonths;
    EXIT WHEN donor_cur%NOTFOUND;
    IF p_idstatus = 20 AND p_paymonths = 0 THEN
      completed_pledge := FALSE;
      EXIT;
    ELSE
      completed_pledge := TRUE;
    END IF;
  END LOOP;
  CLOSE donor_cur;
END ddpay_sp;
/
 

Демонстрация, показывающая разницу из-за exit размещения