![]() | ||||||||||||||||||||||||||||||
![]() |
![]() |
|
|
|||||||||||||||||||||||||||
![]() |
|
Динамические SQL - запросы Oracle для ускорения выборок данныхИсточник: Программист, № 2/2001 Андрей Фионик
Типичная задача при работе с базами данных - выбрать информацию из разных таблиц, отфильтровать ее по определенным критериям, потом обработать и/или выдать пользователю для просмотра и визуального анализа. Если параметры отбора записей имеются в наличии и определены - эта задача решается тривиально, с помощью обычного оператора SQL "SELECT… FROM… WHERE…" - где набор условий, располагаемых после WHERE, всегда определен. Однако, бывают случаи, когда набор параметров отбора данных определяется только перед самим отбором - а изначально, во время проектирования программы, не известен. Например, надо выбрать клиентов, "засветившихся" в базе данных торговой фирмы за определенный срок; или сделавших покупки на сумму больше некоторой заданной. Или приходится искать конкретного человека, используя частично известные анкетные данные… Ситуация усложняется еще больше, если для определения, какие записи нужно выбрать, а какие нет, надо вызывать какую-нибудь функцию, реализующую сложные и ресурсоемкие вычисления. Разумеется, эту функцию без необходимости лучше в обработку не включать… Все перечисленные проблемы можно решить с помощью динамического SQL. Динамический SQL позволяет строить текст запроса непосредственно внутри кода PL/SQL - и затем выполнять его. Соответственно, разработчик может построить текст запроса, включая в него только необходимые, задействованные в текущий момент условия (случай, когда текст SQL-запроса может быть сформирован внутри клиентского приложения, рассматривать не будем - всегда существуют ситуации, когда этого нельзя сделать по каким-нибудь причинам). За работу с динамическими SQL -запросами отвечает пакет dbms_sql. В общем, работа с ним происходит по следующей схеме:
Ниже мы рассмотрим пример использования динамического SQL для поиска человека по (неполным) анкетным данным. Вначале определимся с используемыми структурами данных.
Поля таблицы PersonParticulars:
Процесс получения результатов разобьем на две части: построение текста SQL-запроса и, собственно, его выполнение. Можно оформить это как две хранимые процедуры, можно как одну - пусть разработчик сам решает. Текст SQL-запроса можно формировать как в одну строку, так и в виде коллекции - на случай, если текст окажется слишком длинным. В нашем случае будем использовать коллекцию - несмотря на то, что длина текста запроса будет небольшой. Зачем? А просто так, для примера. Условимся также, что в хранимую процедуру будут передаваться следующие параметры, управляющие поиском:
Если в качестве какого-либо из параметров передано значение NULL - этот параметр при поиске игнорируем. Результаты поиска вернем в виде таблицы в памяти. Для простоты - это будут просто номера найденных людей (значения их ID).
begin /* На этом этапе у нас имеется часть запроса - WHERE, в которой упомянуты только те условия, которые были заданы через непустые параметры хранимой процедуры */ /* Теперь построим текст запроса полностью */ SQLText(1):=’select ID’; /* Получаем идентификатор курсора */ C:=dbms_sql.Open_Cursor; Надеюсь, основные идеи понятны? Ссылки по теме
|
|