Используйте синтаксис OPEN FOR и переменные связывания.
procedure all_carers_param_dy (pPostcode in carer.postcode%type, pAge Number
,pReport out SYS_REFCURSOR)
is
lsql varchar2(500) :='SELECT c.id FROM carer c, cared_for cf,carer_cared_for ccf '
||' where c.id = ccf.carer_id (+)'
||' AND cf.id (+) = ccf.cared_for_id';
begin
if pPostcode is not null and pAge <= 0 then
lsql := lsql||' AND c.postcode like upper(''%''||:1||''%'')';
open pReport for lsql using pPostcode;
elsif pPostcode is null and pAge > 0 then
lsql := lsql||' AND ROUND((MONTHS_BETWEEN(sysdate,c.date_of_birth)/12)) = :1';
open pReport for lsql using pAge;
elsif pPostcode is not null and pAge > 0 then
lsql := lsql ||' AND ROUND((MONTHS_BETWEEN(sysdate,c.date_of_birth)/12)) = :1'
||' AND c.postcode like upper(''%''||:2||''%'')';
open pReport for lsql using pAge, pPostcode;
end if;
end all_carers_param_dy;
/
Динамический SQL сложен, труден для понимания и труден для понимания. Одна из хитрых областей - обработка повторений. Хорошей идеей будет объявлять повторяющиеся секции bolierplate как константы. Также обратите внимание, что мы можем разбить большие строки на несколько строк, не объединяя их с '||'
. Это уменьшает накладные расходы на обслуживание.
create or replace procedure all_carers_param_dy
(pPostcode in carer.postcode%type
, pAge Number
, pReport out SYS_REFCURSOR)
is
lsql varchar2(500) ;
root_string constant varchar2(500) :='SELECT c.id FROM carer c
, cared_for cf,carer_cared_for ccf
where c.id = ccf.carer_id (+)
and cf.id (+) = ccf.cared_for_id';
pc_string constant varchar2(256) :=
' AND c.postcode like upper(''%''||:pc||''%'')';
age_string constant varchar2(256) :=
' AND ROUND((MONTHS_BETWEEN(sysdate,c.date_of_birth)/12)) = :age';
begin
if pPostcode is not null and pAge <= 0 then
lsql := root_string || pc_string;
open pReport for lsql using pPostcode;
elsif pPostcode is null and pAge > 0 then
lsql := root_string || age_string;
open pReport for lsql using pAge;
elsif pPostcode is not null and pAge > 0 then
lsql := root_string || age_string
|| pc_string;
open pReport for lsql using pAge, pPostcode;
end if;
end all_carers_param_dy;
/