Nie jestem pewien, dlaczego zawracasz sobie głowę with
klauzula, jest prostsze bez CTE; wystarczy określić, w której tabeli city
kolumna jest w:
function myfunc(p_city IN VARCHAR2,
p_order IN VARCHAR2)
RETURN SYS_REFCURSOR IS
v_result SYS_REFCURSOR;
begin
OPEN v_result FOR
'select * from tableA ta
inner join tableB tb on tb.some_col = ta.some_col
where :p_city is null or LOWER(ta.city) like ''%''||:p_city||''%''
order by ' || p_order || ' asc'
using p_city, p_city;
return v_result;
end myfunc;
/
Domyśliłem się, że to tabela A, po prostu zmień alias, jeśli to ten drugi. Musisz również określić warunek łączenia między dwiema tabelami. (Zauważyłem również, że dodałem spację przed asc
aby zapobiec łączeniu tego w ciąg uporządkowany według kolejności).
To kompiluje się bez błędów; po uruchomieniu otrzymuję ORA-00942:tabela lub widok nie istnieje, co jest rozsądne. Jeśli tworzę dane fikcyjne:
create table tablea (some_col number, city varchar2(30));
create table tableb (some_col number);
insert into tablea values (1, 'London');
insert into tablea values (2, 'Londonderry');
insert into tablea values (3, 'East London');
insert into tablea values (4, 'New York');
insert into tableb values (1);
insert into tableb values (2);
insert into tableb values (3);
insert into tableb values (4);
wtedy wywołanie go otrzyma:
select myfunc('lond', 'city') from dual;
SOME_COL CITY SOME_COL
---------- ------------------------------ ----------
3 East London 3
1 London 1
2 Londonderry 2
Jeśli naprawdę chcesz z jakiegoś powodu pozostać przy CTE, to (jak powiedział @boneist), musi to być częścią dynamicznego oświadczenia:
OPEN v_result FOR
'with all_prb as (
select * from tableA ta
inner join tableB tb on tb.some_col = ta.some_col
)
select * from all_prb ff
where :p_city is null or LOWER(ff.city) like ''%''||:p_city||''%''
order by ' || p_order || ' asc'
using p_city, p_city;