Немного мозгового штурма:
- Создайте SQL
TYPE
, представляющий тип вашей строки;для получения более подробной информации прочитайте документы Oracle
create type my_table_t as( /* same fields as my_table */ );
Создайте функцию
PIPELINED
, которая получает все необходимые параметры и возвращает нужный вам тип строки.Прочтите
документацию Oracle о конвейерных табличных функциях для получения более подробной информации.В его наиболее общей форме вы получите
varchar2
, содержащий предоставленный пользователем фильтр SQL, но, поскольку он может быть уязвим для атак с использованием инъекций, я предлагаю использовать другие альтернативы, такие как принятие (fk1, ..., fkn) в качестве параметров,Давайте назовем эту функцию
query_my_table
.Внутри этого запроса вы
динамически генерируете именно тот SQL, который вам нужен, открывая
REF CURSOR
и
PIPE
в каждой строке.Поскольку вы генерируете конкретный SQL для каждого случая, вы можете выполнить именно тот запрос, который вам нужен, и вам не нужно полагаться на поведение при просмотре.
create or replace function query_my_table(fk1 number, ..., fkn number) return my_table_t pipelined is
query varchar2;
begin
query := /* Create a string with the exact SQL you need */
/* open ref cursor for query using fk1, ..., fkn */
loop
/* fetch & exit when not_found */
/* load data into instance of my_table_t */
pipe row(my_table_t_instance);
end loop;
/* close ref cursor */
return;
end issue
Затем вы можете SELECT
, выдав:
select * from table(query_my_table(fk1, ..., fkn));
Это просто еще одно применение тех же функций, которые используются dbms_xplan.display
.Основная проблема, с которой я могу столкнуться при таком подходе, заключается в том, что он не очень хорошо компонуется: поскольку у Oracle нет статистики о бите table(...)
, если вы начнете объединять его с другими таблицами, оптимизатор не сможет оптимизироватьстолько.Но если это своего рода «последний запрос», он должен работать нормально.