A cursor is effectively a pointer into a result set. You can't query the cursor like a table.
You can refer to v_var in your cursor query; you just need to handle it being null:
DECLARE
v_var model.serial%type;
cursor r_cur is
select cma.desc, cma.model, cma.serial, smp.id
from model cma
join dictionary smp on smp.dictionary_id = cma.d_id
where (v_var is null and cma.serial is null)
or (v_var is not null and cma.serial = v_var);
BEGIN
-- populate v_var
FOR r_row IN r_cur LOOP
-- do whatever you need to with the row(s)
END LOOP;
END;
/
The is not null is a bit redundant but makes the logic clearer. There's also no point in using like with a single scalar value, so I've switched to =.
You can also parameterise the cursor to make the relationship and flow a bit more obvious:
DECLARE
v_var model.serial%type;
cursor r_cur (c_var model.serial%type) is
select cma.desc, cma.model, cma.serial, smp.id
from model cma
join dictionary smp on smp.dictionary_id = cma.d_id
where (c_var is null and cma.serial is null)
or (c_var is not null and cma.serial = c_var);
BEGIN
-- populate v_var
FOR r_row IN r_cur (v_var) LOOP
-- do whatever you need to with the row(s)
END LOOP;
END;
/
Or use an implicit cursor loop:
DECLARE
v_var model.serial%type;
BEGIN
-- populate v_var
FOR r_rec IN (
select cma.desc, cma.model, cma.serial, smp.id
from model cma
join dictionary smp on smp.dictionary_id = cma.d_id
where (v_var is null and cma.serial is null)
or (v_var is not null and cma.serial = v_var)
) LOOP
-- do whatever you need to with the row(s)
END LOOP;
END;
/
It would still be possible to keep your current cursor query and loop over all the results, using similar logic inside the loop to decide when you've found the row(s) you want to use, and then use PL/SQL assignment instead of a new query:
fetch r_cur into r_cur_single;
if (v_var is null and r_cur_single.serial is null)
or (v_var is not null and r_cur_single.serial = v_var)
then
v_description := r_cur_single.desc;
v_mode := r_cur_single.model;
end if;
but it's probably going to be more efficient to put the filter into the query.