#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
размещения