Oracle
 sql >> Datenbank >  >> RDS >> Oracle

So erstellen Sie dynamisches SQL für mit sys_refcursor in Oracle

Ich bin mir nicht sicher, warum Sie sich mit dem with beschäftigen Klausel, es ist einfacher ohne CTE; Sie müssen nur die Tabelle city identifizieren Spalte ist in:

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;
/

Ich habe vermutet, dass es Tisch A ist, ändern Sie einfach den Alias, wenn es der andere ist. Sie müssen auch die Join-Bedingung zwischen den beiden Tabellen angeben. (Ich habe auch bemerkt, dass ich vor asc ein Leerzeichen eingefügt habe um zu verhindern, dass dies mit der Order-by-Zeichenfolge verkettet wird).

Dies wird ohne Fehler kompiliert; Beim Ausführen erhalte ich ORA-00942:Tabelle oder Ansicht existiert nicht, was vernünftig ist. Wenn ich Dummy-Daten erstelle:

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);

dann wird aufgerufen:

select myfunc('lond', 'city') from dual;

  SOME_COL CITY                             SOME_COL
---------- ------------------------------ ----------
         3 East London                             3
         1 London                                  1
         2 Londonderry                             2

Wenn Sie aus irgendeinem Grund wirklich beim CTE bleiben wollen (wie @boneist sagte), muss das Teil der dynamischen Aussage sein:

  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;