Возможно, вы не знаете ваше значение p_num
до времени выполнения. Это может быть что-то, что вы получаете из другой обработки, или из другой таблицы, или из клиентской среды, или вычисляете как-то.
В качестве тривиального примера:
declare
cursor c1 is
select * from departments;
cursor c2 (p_department_id employees.department_id%type) is
select * from employees
where department_id = p_department_id;
begin
for r1 in c1 loop
-- do something with this department info
dbms_output.put_line(r1.department_name);
-- now loop through empoyees in that department
for r2 in c2 (r1.department_id) loop
-- do something with this employee info
dbms_output.put_line(' ' || r2.first_name);
end loop;
end loop;
end;
/
Administration
Jennifer
Marketing
Michael
Pat
Purchasing
Den
Alexander
...
Курсор c2
ищет для сотрудников в одном отделе, но это не может быть жестко запрограммировано.
Вы можете сделать то же самое с эквивалентом вашей конструкции d2
, то есть назначить отдельную локальную переменную, которую будет использовать внутренний курсор по-прежнему используется - поскольку он открывается и оценивает переменную в этот момент:
declare
l_department_id departments.department_id%type;
cursor c1 is
select * from departments;
cursor c2 is
select * from employees
where department_id = l_department_id;
begin
for r1 in c1 loop
-- do something with this department info
dbms_output.put_line(r1.department_name);
-- ...
-- now loop through empoyees in that department
l_department_id := r1.department_id;
for r2 in c2 loop
-- do something with this employee info
dbms_output.put_line(' ' || r2.first_name);
end loop;
end loop;
end;
/
... но наличие параметра делает более понятным, что значение должно измениться, и исключает возможность двух вызовов и забыв изменить значение между ними.
В обоих случаях фактический SQL запроса курсора будет обрабатываться как имеющий переменную связывания; разница заключается только в том, как это заполнено.
Очевидно, что вы бы на самом деле не выполняли эту конкретную задачу с помощью вложенных циклов или любого PL / SQL; и во многих местах этот вид конструкции применяется так же, или запросы могут быть по крайней мере объединены в один курсор с объединением.
Это может быть полезно для более сложных логик c Например, если существует несколько путей, по которым может идти код, и несколько необязательных вторичных курсоров, и все нуждаются в информации из одного и того же (дорогого) базового запроса, и вы не хотите повторно присоединяться к базовым таблицам.
Как и в большинстве построчных обработок, я подозреваю, что они используются чаще, чем это действительно необходимо. Это все еще полезный инструмент для доступа.