procedure foo(p1 IN INTEGER,
p2 IN INTEGER,
ooo out sys_refcursor)
is
begin
open ooo for
select T1.*
from T1
where T1.x=p1
and (
p2 in (SELECT z from T2 where T2.someId=T1.SomeId and T2.y=12)
or
not exists (SELECT z from T2 where T2.someId=T1.SomeId and T2.y=12)
);
end;
A subconsulta é exatamente a mesma nas duas vezes. Existe uma maneira de refatorá-lo para ser especificado apenas uma vez? Pelo menos no Oracle.
Uma maneira seria usá-lo como uma junção:
procedure foo(p1 IN INTEGER,
p2 IN INTEGER,
ooo out sys_refcursor)
is
begin
open ooo for
select unique T1.*
from T1
left join T2 on T2.someId=T1.SomeId and T2.y=12
where T1.x=p1
and (
p2 = T2.z
or
T2.z is null -- T2.z is a NOT NULL column
);
end;
Mas isso não é equivalente (adicionei UNIQUE para filtrar as linhas multiplicadas devido à junção, mas isso também remove possíveis linhas duplicadas corretas de T1).
PS: Fiz um SQL Fiddle com as duas consultas de cima e as duas respostas de baixo.