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

1 ... 139 140 141 [ 142 ] 143 144 145 ... 264


where quota is null;

else (

exec sql delete from salesreps

where quota = .amount;

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

Выборка данных с помощью встроенного SQL

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

Встроенный SQL должен создать мост между табличной логикой инструкции select и последовательной обработкой строк в С, COBOL и других базовых языках. Поэтому во встроенном SQL запросы делятся на две группы:

Запросы, возвращающие одну запись, где ожидаемые результаты запроса представляют собой одну строку данных. Запрос о лимите кредита одного клиента или об объеме продаж и плане продаж одного служащего являются примерами таких запросов.

Запросы, возвращающие набор записей, где ожидаемые результаты запроса могут содержать одну, ни одной или несколько строк данных. Запрос о заказах на сумму свыше $20000 или об именах служащих, работающих с опережением плана, являются примерами таких запросов.

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

Запросы, возвращающие одну запись

Многие запросы SQL возвращают одну строку результата. Такие запросы особенно распространены в программах обработки транзакций, где пользователь вводит идентификатор клиента или номер заказа и программа извлекает соответствующие данные о клиенте или заказе. Во встроенном SQL запросы этого типа вьшолняются с помощью одиночной инструкции select, синтаксическая диаграмма которой изображена на рис. 17.19. Одиночная инструкция select очень похожа на интерактивную; она содержит предложение select, предложение from и необязательное предложение where. Поскольку одиночная инструкция select возвращает одну строку данных, *1ет необходимости в предложениях group by, having или order by. В предложении Into указывается базовая переменная, которая принимает данные, извлеченные ин-трукцией.



SELECT-

ALL-

I- DISTINCT-

возвращаемыО столбец

>-► INTO -;

-- базовая переменная -

-k. FROM -

J-спецификация таблицы -,

► WHERE условие от6ора

Рис.

SSXiECn

Ha рис. 17.20 предстаалена простая программа с одиночной инструкцией select. Программа запрашивает у пользователя идентификатор и затем извлекает имя, план продаж и объем продаж служащего с таким идентификатором. Эти три элемента данных СУБД помещает в базовые переменные repname, repquota и repsales соответственно.

main о

exec sql begin declare section;

int repnum; /* идентификатор служащего (вводит пользователь) */

char repname[16J; /* полученное имя служащего */

float repquota; /* полученный план */

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

exec sql end declare section;

/ Запросить у пользователя идентификатор служащего */ printf ( Введите идентификатор служащето; ); scanf( %d , srepnum);

/* Выполнить SQL-запрос */

exec sql select name, quota, sales

from salesreps where empl num = :repnum

into :repname, :repquota, :repsales;

/* Отобразить полученные данные */ if (sqlca.sqlcode == 0){

printf( Имя: %s\n , repname);

printf( План: %f\n , repquota);

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

else if (sqlca.sqlcode == 100)

printf( Неправильный идентификатор служащего.\n ); else

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

1,7,20. Применение одиночной

mSELECT



Вспомним, что базовые переменные, которые использовались в инструкциях xnsert, delete и update, были входными переменными. в противоположность это-

базовые переменные, заданные в предложении into одиночной инструкции select, являются выходными переменными. Каждая базовая переменная, указанная в предложении into, получает один столбец из строки результатов запроса. Выбираемые столбцы и соответствующие им базовые переменные образуют пары в порядке расположения в своих предложениях, и число столбцов должно равняться числу переменных. Кроме того, тип данных каждой переменной должен быть совместимым с типом данных соответствующего столбца.

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

Текстовые данные переменной длины также необходимо преобразовывать перед тем, как записывать их в базовую переменную. СУБД, как правило, преобразует данные типа varchar в строку, заканчивающуюся нулевым символом, для программ на языке Сив строку переменной длины (первый символ указывает длину) для программ на языке Pascal. В програ.ммах на языках COBOL и FORTRAN базовая переменная должна быть объявлена, в общем случае, как структура данных, состоящая из целочисленного поля счетчика и массива символов. СУБД возвращает символы данных в массив, а длину данных - в поле счетчика этой структуры.

Если в СУБД имеются данные типов date, time или каких-либо еще, то необходимы соответствующие преобразования. Некоторые СУБД возвращают представленные во внутреннем формате значения даты и времени в целочисленную базовую переменную. Другие преобразуют данные типа date/time в текстовый формат и возвращают их в строковую переменную базового языка. В табл. 17 2 были описаны преобразования типов данных, обычно осуществляемые в СУБД, но чтобы получить полную информацию, необходимо обратиться к документации по встроенному SQL для СУБД конкретного типа.

Ошибки при извлечении записей

Одиночная инструкция select, подобно всем остальным встроенным инструкциям SQL, присваивает значение переменным sqlcode и sqlstate, чтобы показать, как завершилось ее выполнение:

Если одна строка результатов запроса успешно извлечена, переменной sqlcode присваивается значение ноль, а переменной sqlstate - 00000; базовые переменные, указанные в предложении into, содержат полученные значения. Если во время выполнения инструкции произошла ошибка, переменной sqlcode присваивается отрицательное значение, а переменной sqlstate - ненулевой класс ошибки (первые два символа из пяти); это означает, что требуемые данные не были извлечены и в базовых переменных отсутствуют.

Если не была извлечена ни одна строка результатов запроса, в переменной sqlcode возвращается специальное значение, соответствующее предупреждению not found, а переменной sqlstate присваивается класс ошибки no data. Если было извлечено более одной строки результатов запроса, то это считается ошибкой и возвращается отрицательное значение переменной sqicode., , .



1 ... 139 140 141 [ 142 ] 143 144 145 ... 264

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