Программирование >>  Sql: полное руководство 

1 ... 148 149 150 [ 151 ] 152 153 154 ... 264


выполняемые инструкции похожи друг на друга, то такой расход машинного времени будет просто расточительством. На практике инструкция execute immediate подходит для одноразового выполнения инструкции, повторять которую в дальнейшем не планируется.

Для исправления этой ситуации в динамическом SQL сушествует альтернатив-ньсй, двухэтапный метод выполнения запросов SQL. Вот вкратце его суть;

1. Профамма создает в буфере сфоку инструкции SQL, как и в случае с инструкцией execute immediate. Любая константа в тексте инструкции может быть заменена вопросительным знаком; это говорит о том, что значение константы будет предоставлено позднее. Вопросительный знак называется маркером параметра.

2. Инструкция prepare дает команду СУБД произвести синтаксический анализ инструкции, проверить ее правильность, оптимизировать и создать план выполнения. СУБД присваивает некоторое значение переменным sqlcode/sqlstate, чтобы сообшить о любых ошибках, обнаруженных в инструкции, и сохраняет план выполнения. Обратите внимание на то, что, когда СУБД выполняет инсфукцию prepare, она не выполняет соответствуюший план.

3. Если профамме фебуется вьшолнить подготовленную ранее инсфукцию, она передает в СУБД инструкцию execute вместе со значениями всех маркеров параметров. СУБД подставляет значения парамефов, исполняет ранее подготовленный план и присваивает код завершения переменным sqlcode/sqlstate.

4. Профамма может многократно выполнять инсфукцию execute, всякий раз изменяя значения парамефов.

На рис. 18.4 представлен текст профаммы на языке С, которая осушествляет последовательность приведенных выше действий. Эта профамма выполняет обновление таблиц. Она запрашивает у пользователя имена таблицы и двух столбцов, а затем формирует для данной таблицы инсфукцию update, имеющую следующий вид:

update имя таблицы

set имя второго столбца = ? where имя первого столбца ~- ?

Таким образом, информация, вводимая пользователем, задает обновляемую таблицу, обновляемый столбец и используемое при обновлении условие отбора. Сравниваемое значение в условии отбора и новые значения данных задаются как пара-мефы, которые будут переданы позже, при выполнении инструкции execute.

main {) (

/* Это универсальная программа. Ее можно использовать для любой

инструкции обновления, в которой необходимо модифицировать числовой столбец во всех строках таблицы, где другой числовой столбец имеет определенное значение. Например, эту программу можно использовать для обновления планов некоторых служащих или обновления лимита кредита для некоторых клиентов.

exec sql include sqlca;

exec sql begin declare section;

char stmtbuf[301]; /* текст инструкции SQL */

float search value; /* параметр для сравнения */

Риа 18.4. Применение инструкции PREPARE и EXECUTE



float new value; параметр для обновления */

exec sql end declare section;

char tblname[31]; /* имя обновляемой таблицы */

char searchcol[31]; /* имя сравниваемого столбца */

char updatecol[31]; /* имя обновляемого столбца */

char yes no[31]; /* ответ yes/no от пользователя */

/* Запросить у пользователя имена столбцов и таблицы */ prmtf ( Введите имя обновляемой таблицы: ); gets(tblname);

printf( Введите имя сравниваемого столбца: ); gets(searchcol);

printf( Введите имя обновляемого столбца: ); gets(updatecol);

/* Сформировать в буфере инструкцию SQL */

sprintf (stmtbuf, update %s set %s = ? where %s = T,M-(T)

tblname, updatecol, searchcol);

exec sql prepare mystmt from :stmtbuf; -M-@

if (sqlca.sqlcode) (

printf( Ошибка при выполнении инструкции PREPARE: %ld\n , sqlca.sqlcode);

exit (1);

/* Цикл, в котором запрашиваются параметры и выполняются обновления */ for ( ; ; ) (

printf( ХпВведите сравниваемое значение для %s: , searchcol); scanf( %f , &search value);

printf( Введите новое значение для %s: , updatecol!; scanf( %f , &new value);

/* Выполнить инструкцию SQL */

exec sql execute mystmt using :new value, :search value; -©

if (sqlca.sqlcode) {

printf ( Ошибка при выполнении инструкции EXECUTE: %ld\n , sqlcXsqlcode) ;

exit (1);

/* Будет ли вьтолняться следующее обновление? */

printf( Еще (у/п)? );--

gets(yes no); If (yes no[0] == n) break;

printf( \пОбновления завершены.\n ); exit(0);


Рис. 18.4. Применение инструкций PREPARE и EXECUTE

После формирования в буфере текста инструкции update программа с помощью инструкции prepare дает СУБД команду произвести компиляцию инструкции update. Затем программа входит в цикл, запрашивая у пользователя значения параметров для выполнения ряда последовательных обновлений таблицы. Приведенный ниже диалог пользователя с компьютером показывает, как программа, представленная на рис. 18.4, обновляет личные планы служащих:



Введите имя обновляемой таблицы: staff Введите имя сравниваемого столбца: empl num Введите имя обновляемого столбца: quota

Введите сравниваемое значение для empl num: 106

Введите новое значение для quota: 150000.00 Еще (у/п) > у

Введите сравниваемое значение для empl num: 102

Введите новое значение для quota: 225000.00 Еще (у/п) у

Вьедите сравниваемое значение для empl num: 107

Введите новое значение для quota: 215000.00 Еще (у/п)? п

Обновления завершены.

Данная программа является прекрасной иллюстрацией ситуации, в которой необходимо двухэтапное динамическое выполнение инструкции. СУБД компилирует динамическую инструкцию update только один раз, а выполняет три раза - по одному разу для каждого набора значений параметров, вводимых пользователем. Если бь[ в программе использовалась инструкция execute immediate, то динамическая инструкция update компилировалась и выполнялась бы по три раза Таким образом, двухэтапное динамическое выполнение с помощью инструкций prepare и execute помогает устранить некоторые недостатки динамического SQL, снижающие производительность СУБД. Как уже упоминалось, такой же подход применяется во всех программных интерфейсах SQL, описываемых в следующей главе.

Инструкция PREPARE

Инструкция prepare, синтаксическая диафамма которой изображена на рис 18.5, применяется только в динамическом SQL. Она принимает базовую переменную, содержащую строку инсфукции SQL, и передает эту инсфукцию в СУБД. СУБД компилирует текст инструкции и подготавливает ее к выполнению, создавая план выполнения. СУБД присваивает также соответствующие значения переменным sql-code/sqlstate, чтобы Сообщить пользователю обо всех ошибках, обнаруженных в тексте инсфукции. Как уже говорилось, вместо любой константы сфока инсфукции может содержать маркер парамефа, обозначаемый вопросительным знаком. Этот маркер дает СУБД сигнал о том, что значение парамефа будет передано позднее, при выполнении инсфукции.

PREPARE имя инструкции FROM базовая переменная -

Рис. 18 5. Синтаксическая диаграмма инструкции PREPARE

Инструкция prepare присваивает подготавливаемой инструкции имя. Это имя является идентификатором SQL, подобно имени набора записей. Имя инструкции задается в последующих инструкциях execute. Длительность хранения подготовленной инструкции, а также ее имени различается в зависимости от СУБД. Иногда СУБД



1 ... 148 149 150 [ 151 ] 152 153 154 ... 264

© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика