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

1 ... 151 152 153 [ 154 ] 155 156 157 ... 264


Обратите внимание на то, что данная профамма копирует имя столбца для каждого парамефа в сфуктуру sqlname. Это делается исключительно для удобства; когда область sqlda применяется дпя передачи параметров, субд игнорирует сфук-туру sqlname.

Вот пример диалога между пользователем и профаммой, исходный текст которой изображен на рис. 18.8:

*** Программа обновления данных о служащих ***

Обновить столбец NAME (у/п)? Y Обновить столбец REP OFFICE (у/п)? у Обновить столбец MANAGER (у/п)? п Обновить столбец HIRE DATE (у/п)? п Обновить столбец QUOTA (у/п)? у Обновить столбец SALES (у/п)? п

Введите идентификатор служащего: 106 Введите новое значение для столбца NAME: Sue Jackson Введите новое значение для столбца REP OFFICE: 22 Введите новое значение для столбца QUOTA: 175000.00

Введите идентификатор служащего: 104

Введите новое значение для столбца NAME: Joe Smith

Введите новое значение для столбца REP OFFICE: *

Введите новое значение для столбца QUOTA: 275000.00

Введите идентификатор служащего: О

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

На основе первоначальных ответов пользователя профамма формирует следующую динамическую инсфукцию update и передает ее инсфукции prepare:

update salesreps

set name = ?, office = ?, quota = ? where erapl nura = ?

В инструкции заданы четыре парамефа, и прОфамма выделяет область sqlda, достаточно больщую для того, чтобы разместить в ней четыре сфуктуры sqlvar. Когда пользователь вводит первый набор значений параметров, динамическая инструкция update принимает следующий вид:

Update salesreps

set name = Sue Jaclcson, office = 22, quota = 175000.00 here erapl nura =10 6

После ввода второго набора значений парамефов она принимает следующий вид:

Pdate salesreps

set name = Joe Smith, office = NULL, quota = 275000.00 where empl nura = 104

Приведенная профамма кажется довольно сложной, но по сравнению с реальными утилитами обновления баз данных она достаточно проста. В ней применяются все средства динамического SQL, необходимые для динамического выполнения ин- > струкций с переменным числом парамефов.



Динамические запросы на выборку

Рассмотренные до сих пор инструкции execute immediate, prepare и execute обеспечивают динамическое выполнение большинства инсфукций SQL. Но они не поддерживают динамические запросы на выборку, поскольку у них отсутствует механизм обработки результатов запроса. Д;ш выполнения динамических запросов инструкции prepare И execute динамического SQL объединяются с расширенными инсфукциями статического SQL, обеспечивающими обработку результатов запроса, а также вводится новая инсфукция. Вот последовательность действий, осуществляемых программой при выполнении динамического запроса на выборку:

L Динамическая версия инсфукции declare cursor объявляет набор записей для запроса. В отличие от статической инструкции declare cursor, которая содержит внутри себя саму инсфукцию select, динамическая форма инсфукции declare cursor Содержит только имя динамической инсфукции select.

2. Профамма формирует инсфукцию select в буфере аналогично тому, как она формирует динамическую инсфукцию update или delete Инсфукция select, как и другие динамические инсфукции SQL, может содержать маркеры параметров

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

4. Посредством инсфукции describe профамма запрашивает у СУБД описание таблицы результатов запроса, которая будет создана при выполнении запроса СУБД возвращает описание каждого столбца таблицы в область данных SQL (sqlda), указанную профаммой, информируя профамму о том, сколько столбцов имеет таблица результатов запроса, каковы имя каждого столбца, тип и длина содержащихся в нем данных. Инсфукция describe используется исключительно при формировании динамических запросов на выборку.

5. Профамма использует описания столбцов, находящиеся в области sqlda, чтобы выделить блоки памяти для приема столбцов из таблицы результатов запроса. Профамма может также выделить место дпя переменных-индикаторов, сопровождающих столбцы. Чтобы сообщить СУБД, куда следует возвращать результаты запросов, профамма помещает адреса этих блоков памяти и адреса переменных-индикаторов в sqlda.

6. Динамическая версия инсфукции open дает СУБД команду начать выполнение запроса и передает ей значения парамефов, заданные в динамической инсфукции select. ИнСфукция open устанавливает указатель набора записей на позиции, предшествующей первой сфоке в таблице результатов запроса.

7. Динамическая версия инсфукции fetch перемещает указатель набора записей на первую сфоку в таблице результатов запроса, извлекает данные и записывает их в соответствующие области данных и в переменные-индикаторы В отличие от статической инструкции fetch, которая содержит список базовых переменных, принимающих данные, динамическая инсфукция fetch использует область sqlda, чтобы сообщить СУБД, куда возвращать данные. Последующие инсфУК-ции fetch продвигаются по таблице результатов запроса от сфоки к сфоке, перемещая указатель набора записей на следующую сфоку и извлекая из нее данные в соответствующие области данных профаммы.



8. Инструкция CLOSE прекращает доступ к таблице результатов запроса и ликвидирует связь между нею и набором записей. Эта инструкция идентична инструкции CLOSE в статическом SQL; никакие расширения инструкции для обеспечения возможности реализации динамических запросов не требуются. Программирование динамического запроса - это более трудоемкая задача по сравнению с формированием любой другой встроенной инструкции SQL. Однако этот процесс, как правило, является скорее утомительным, чем сложным. На рис. 18.9 изображена небольшая профамма формирования запросов к базе данных, которая с помощью динамического SQL извлекает данные и отображает на экране выбранные столбцы из заданной пользователем таблицы. Кружки с цифрами на рисунке соответствуют восьми пунктам, перечисленным выше.

main()

Эта простая универсальная программа предназначена для выполнения запросов. Она запрашивает у пользователя имя таблицы, а затем спрашивает, какие имена столбцов должны быть включены в запрос. После того как пользователь делает выбор, программа выполняет требуемый запрос и отображает результаты на экране.

exec sql include sqlca;

exec sql include sqlda;

exec sql begin declare section;

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

char querytbl[32]; /* указанная пользователем таблица */

char querycol[32]; /* указанный пользователем столбец */

exec sql end declare section;

/* Набор записей, служащий для формирования запроса к системному каталогу

на выборку имен столбцов */ exec sql declare tblcurs cursor for

select colname from system.syscolumns where tblname :querytbl and owner = user;

exec sql declare qrycurs cursor for querystmt;--©

/* Структуры данных */

int colcount = 0; /* число выбранных столбцов */

struct sqlda *qry da; /* область SQLDA, выделенная ддя

запроса */

struct sqlvar *qry var; /* структура SQLVAR для текущего

столбца */

int i; /* индекс для массива структур SQLVAR

в области SQLDA */ char inbufflOl] /* значение, введенное пользователем */

/* Запросить у пользователя имя таблицы */

printf{ *** Программа формирования запросов ***\п\п );

printf( Введите имя таблицы, к которой будет выполняться запрос: );

gets(querytol);

/* Начать формирование инструкции SELECT в буфере */

strcpy (stmtbuf, select ) -ф

/* Обработка ошибок */

exec sql whenever not found goto no m.ore columns;

c. 18.9. Выборка датыж с помощьюдина*ичвского SQL



1 ... 151 152 153 [ 154 ] 155 156 157 ... 264

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