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

1 ... 141 142 143 [ 144 ] 145 146 147 ... 264


выполнением встроенной инструкции, и это значение становится частью инструкции SELECT, которая будет выполняться в СУБД. Значение переменной в СУБД не изменяется. И Переменная repname - это выходная базовая переменная, используемая для передачи данных из СУБД в программу. СУБД присваивает этой переменной значение во время выполнения встроенной инструкции SELECT. После того как инструкция будет выполнена, программа может использовать полученное значение. Входные и выходные базовые переменные объявляются в программе одинаково и во встроенной инструкции SELECT обозначаются также одинаково: с помощью двоеточия. Однако при написании программы не следует забывать о различии между ними. Входные переменные можно применять в любой инструкции SQL, где присутствует константа. Выходные переменные можно применять только в одиночной инструкции SELECT и в инструкции FETCH, рассматриваемой ниже в настоящей главе.

Запросы, возвращающие набор записей

Когда результатом выполнения запроса является не одна запись, а целая таблица, встроенный SQL должен обеспечить для прикладной программы возможность построчного получения результатов запроса. Для этого во встроенном SQL вводится понятие указателя набора записей (cursor) и добавляется несколько новых инструкций. Вот вкратце механизм выполнения запроса данного типа и требуемые для этого новые инструкции:

L Инструкция DECLARE CURSOR Определяет выполняемый запрос и связывает имя набора записей с данным запросом.

2. Инструкция OPEN дает команду СУБД, чтобы она начала выполнять запрос и создавать таблицу результатов запроса. Эта инструкция устанавливает указатель набора записей перед первой строкой таблицы результатов.

3. Инструкция FETCH продвигает указатель набора записей на первую строку таблицы результатов и извлекает данные, записывая их в базовые переменные прикладной программы. Последующие инструкции FETCH перемещаются по таблице результатов строка за строкой, продвигая указатель на следующую строку и извлекая из нее данные с последующей их записью в базовые переменные.

4. Инструкция CLOSE прекращает доступ к таблице результатов и ликвидирует связь между указателем набора записей и таблицей результатов.

На рис. 17.23 представлен текст программы, выполняющей с помощью встроенного SQL простой запрос, возвращающий набор записей. Цифры в кружочках на рисунке соответствуют номерам перечисленных выше этапов. Программа извлекает и отображает на экране в алфавитном порядке имя, личный план и текущий объем продаж для каждого служащего, чей объем продаж превышает личный план. Соответствующий интерактивный запрос SQL, извлекающий эту информацию, имеет следующий вид:

SELECT NAME, QUOTA, SALES FROM SALESREPS WHERE SALES > QUOTA ORDER BY NAME



main О {

exec sql include sqlca;

exec sql begin declare section;

char repname[16]; /* полученное имя служащего */ float repquota; /* полученный план */

float repsales; /* полученный объем продаж */

short repquota ind; /* индикатор нулевого плана */

exec sql end declare section;

/* Объявить набор за[1исей для запроса */

exec sql declare repcurs cursor for -

select name, quota, sales

from salesreps where sales > quota order by name;

/* Обработка ошибок */ whenever sqlerror goto error; whenever not found goto done;

/* Открыть набор записей, чтобы начать запрос */

exec sql open repcurs; .4-

/* Перебрать все строки таблицы по очереди */ for ( ; ; ) {

/* Извлечь следующую строку */

exec sql fetch repcurs-<-@

into -repname, -.repquota : repquota ind, :repsales,

/* Отобразить полученные данные */ printf{ Имя: %s\n , repname); if (repqaota ind < 0)

printf( План не назначен.\n ); else

printf( План: %f\n , repquota); printf( Объем продаж. %f\n , repsales),

error:

printf( Ошибка SQL; %ld\n , sqlca.sqlcode); exit(1);

done:

/* Запрос выполнен. Закрыть набор записей */

exec sql close repcurs;.-

exit(0),

Риа 17. 23. Выполнение многострочного запроса

Обратите внимание на то, что этот запрос, слово в слово, присутствует во встроенной инструкции DECLARE CURSOR на рис. 17.23. Инструкция также связывает имя набора записей repcurs с данным запросом. Имя набора записей используется затем в инструкции OPEN, чтобы начать выполнение запроса и установить указатель набора записей перед первой строкой в таблице результатов запроса.

Инструкция FETCH внутри цикла for при каждом прохождении цикла передает в программу очередную запись из таблицы результатов запроса Предложение INTO в инсгрукции FETCH Ифасг ту Же самую роль, что и в одиночной инструкции SELECT-В этом предложении задаются базовые переменные, принимающие данные, - по одной базовой переменной для каждого столбца из таблицы результатов запроса Как



и в предыдущих примерах, для получения данных, которые могут содержать значения null, используется переменная-индикатор (repquota and).

Когда в программу переданы все строки и больще передавать нечего, инструкция fetch возвращает предупреждение not found. Код предупреждения здесь такой же, как и в случае, когда одиночная инструкция select не может извлечь строку данных. Инструкция whenever not found дает Препроцессору команду сгенерировать подпрограмму, которая проверяет значение переменной sqlcode после выполнения инструкции fetch. Эта подпрограмма осуществляет переход к метке done при наличии предупреждения not found и к метке error при возникновении ошибки. В конце программы инструкция close завершает запрос и прекращает доступ программы к таблице результатов запроса.

Указатели наборов записей

Как видно из программы, представленной на рис. 17.23, указатель набора записей во встроенном SQL очень похож на имя или дескриптор файла в таких языках программирования, как С или COBOL. Программа открывает набор записей, чтобы получить доступ к таблице результатов запроса, точно так же как она открывает файл, чтобы получить доступ к его содержимому. Аналогично этому, программа закрывает файл, чтобы прекратить к нему доступ, и закрывает набор записей, чтобы прекратить доступ к результатам запроса. И наконец, указатель набора записей отслеживает текущую позицию в таблице результатов запроса точно так же, как дескриптор файла отслеживает текущую позицию внутри открытого файла. Эти параллели между файлами и наборами записей в SQL облегчают прикладным программистам понимание того, что такое указатель набора записей.

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

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

Инструкция DECLARE CURSOR

Инструкция declare cursor, синтаксическая диаграмма которой изображена на рис. 17.24, определяет запрос, который будет выполняться. Инструкция также связывает имя набора записей и запрос. Имя набора записей должно быть допустимым идентификатором SQL. Оно используется для идентификации запроса и его результатов в других встроенных инструкциях SQL и не является базовой переменной.



1 ... 141 142 143 [ 144 ] 145 146 147 ... 264

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