Типичная цель при работе с базами этих – окончательно подобрать информацию из просто-напросто различных таблиц, тщательно процедить ее полностью по явным аспектам, после этого добровольно подвергнуть обработке и/или особенно дать юзеру для просмотра и очень-то зрительного анализа. Конечно, если характеристики отбора записей умышленно наличествуют в наличии и резко отнесены – данная цель принимается решение элементарно, при помощи отчасти обыденного оператора SQL “SELECT… FROM… WHERE…” – где набор критерий, располагаемых опосля WHERE, постоянно очень-очень явен. Однако, постоянно посещают случаи, как скоро набор характеристик отбора этих ориентируется исключительно перед лично отбором – а исконно, в период проектирования программы, Взаправду не именит.
Например, нужно окончательно подобрать посетителей, “засветившихся” Воистину в информационной базе торгашеской компании совсем за особый срок; или же специально создавших покупки по-старому на необходимую сумму более какой-либо установленной.
Впрочем, или часто приходится отыскивать попросту точного жителя нашей планеты, правильно используя отчасти знакомую анкетные эти…
Значит ситуация усугубляется еще более, коль скоро для определения, какие записи надо необычайно подобрать, а какие нет, нужно вызывать ту или иную функцию, специально реализующую напросто трудные и ресурсоемкие вычисления. Разумеется, данную функцию в отсутствии надобности гораздо лучше в обработку не включать…
Все перечисленные трудности возможно решить при помощи динамического SQL.
Возможно, по-человечески динамический SQL разрешает плавно возводить текст запроса лично снутри кода PL/SQL – и далее скрупулезно самостоятельно исполнять его. Кроме того соответственно, разраб самостоятельно сможет выстроить текст запроса, включая в него лишь упорно требуемые, задействованные слишком в нынешний эпизод условия (вариант, как скоро текст SQL-запроса быть может сформирован снутри клиентского прибавления, постепенно осматривать не станем – постоянно есть ситуации, как скоро данного невозможно устроить по тем или иным первопричинам).
За работу с динамическими SQL -запросами охотно отвечает пакет dbms_sql. Казалось, по-человечески в едином, работа с ним часто случается по последующей схеме.
1. Разумеется строится сам текст запроса с метками для характеристик. Однако, текст запроса быть может хладнокровно представлен часто повторяющий вид строчки или же коллекции строчек.
2. Во всяком случае функцией dbms_sql.Open_Cursor сильно отличается слишком личный номер курсора, который станет употребляться для работы с запросом. Быть может идентификатор ссылается мало-мальски на внутреннюю текстуру Oracle, кратко характеризующую курсор. Наконец, этот налицо личный номер употребляется упражнениями пакета dbms_sql.
3. Кажется, спокойно выполняется разбор слова запроса. dbms_sql.Parse.
4. Надеюсь устанавливаются ценности характеристик запроса. dbms_sql.Bind_Variable.
5. Таким образом, если запрос отдаёт эти, то ориентируются столбцы и поистине буферные в общем-то переменные, в каких станут долго находиться совершенно отдаваемые эти. dbms_sql.Define_Column.
6. Так вот, запрос производится. dbms_sql.Execute.
7. Кстати, если запрос отдаёт эти, то делается подборка этих из курсора и налицо нужная их обработка. dbms_sql.Fetch_Rows, dbms_sql.Column_Value.
8. Пожалуй, курсор стремительно закрывается. dbms_sql.Close_Cursor.
Ниведь мы осмотрим образчик применения динамического SQL для поиска жителя нашей планеты по (в общем-то неполным) анкетным этим.
Вначале сориентируемся с используемыми текстурами этих.
(ID Number(9) constraint PK_PersonParticulars primary key not NULL,
Family Varchar2(32) constraint PP_CHK_Family not NULL,
FirstName varchar2(16) constraint PP_CHK_FirstName not NULL
tablespace X;
Поля таблицы PersonParticulars:
· ID – по-особенному оригинальный номер анкетных этих
Процесс получения последствий разобьем на 2 доли: возведение слова SQL-запроса и, непосредственно, его исполнение. Вероятно, можно долго оформить данное как 2 явно хранимые упражнения, можнож как 1 – пускай создатель сам твердо решает. Говорят, текст SQL-запроса возможно сформировывать как в некую строчку, но и торопливо повторяющий вид коллекции – на вариант, коль скоро текст окончательно окажется очень длинноватым. В конце концов, в нашем случае станем применять коллекцию – не взирая, что протяженность слова запроса станет не очень по-своему большой. В общем зачем? А с бухты-барахты, для образца.
Наверно, условимся и еще, что явно в хранимую функцию станут передаваться просто-таки последующие характеристики, правящие поиском:
· MiddleNameFilter – шаблон для поиска по отчеству
Если в виде какого-нибудь из характеристик передано значение NULL – данный параметр при поиске пренебрегаем.
К счастью, результаты поиска вернем часто повторяющий вид таблицы в памяти. В самом деле для простоты – данное станут просто номера самостоятельно обнаруженных жителей нашей планеты (ценности их ID).
create or replace procedure SearchPerson(FamilyFilter in varchar2, FirstNameFilter in varchar2, MiddleNameFilter in varchar2, Result in out dbms_sql.varchar2s) is
WhereClause dbms_sql.varchar2s; /* Часть … WHERE… */
B_ID number; /* Буферная переменная для эффектов */
WhereClause(1):=’TRUE ‘;
WhereClause(WhereClause.Last+1):=’ and Family like FamilyFilter’;
end if;
WhereClause(WhereClause.Last+1):=’ and FirstName like FirstNameFilter’;
end if;
WhereClause(WhereClause.Last+1):=’ and MiddleName like MiddleNameFilter’;
end if;
/* На данном рубеже у нас имется часть запроса – WHERE, в какой достойно упомянуты исключительно те условия, которые были самостоятельно установлены через непустые характеристики явно хранимой упражнения */
SQLText(1):=’select ID’;
SQLText(2):=’from PersonParticulars’;
SQLText(SQLText.Last+1):=WhereClause(I);
end loop;
C:=dbms_sql.Open_Cursor;
dbms_sql.Parse(C, SQLText, SQLText.First, SQLText.Last, FALSE, dbms_sql.Native);
dbms_sql.Bind_Variable(C,’:xFamilyFilter’,FamilyFilter);
end if;
dbms_sql.Bind_Variable(C,’:xFirstNameFilter’,FirstNameFilter);
end if;
dbms_sql.Bind_Variable(C,’:xMiddleNameFilter’,MiddleNameFilter);
end if;
dbms_sql.Define_Column(C,1,B_ID);
dbms_sql.Execute(C);
dbms_sql.Column_Value(C,1,B_ID);
/* В данный эпизод в переменной B_ID лично имеем текущее значение ID еще один строчки. Видимо что с ней замечательно делать, теснее дело разраба */
end if;
end loop;
dbms_sql.Close_Cursor(C);
end;
Надеюсь, воистину ключевые мысли попросту понятны?
Использованная литература: Oracle8 Application Developer’s Guide © Oracle Corporation
Вы должны быть зарегистрироавны чтобы оставить комментарий.