Скачиваний:
20
Добавлен:
01.04.2014
Размер:
180.74 Кб
Скачать

Into :id_num, :salesperson, :loc, :comm

FROM Salespeople

WHERE snum = 1001;

340 ПОНИМАНИЕ SQL

______________________________________________________________________

ГЛ. 25

Выбранные значения помещаются в переменные с упорядоченными име-

нами указанными в предложении INTO. Разумееется, переменные с име-

нами указанными в предложении INTO должны иметь соответствующий

тип чтобы принять эти значения, и должна быть своя переменная для ка-

ждого выбранного столбца.

Если не учитывать присутствие предложения INTO, то этот запрос - по-

хож на любой другой. Однако, предложение INTO добавляет значитель-

ное ограничение к запросу. Запрос должен извлекать не более одной ст-

роки. Если он извлекает много строк, все они не могут быть вставлены

одновременно в одну и ту же переменную. Команда естественно потер-

пит неудачу. По этой причине, SELECT INTO должно использоваться

только при следующих условиях:

* когда вы используете предикат проверяющий значения, которое как вы

знаете, могут быть уникальным, как в этом примере. Значения которые,

как вы знаете, могут быть уникальными - это те значения которые име-

ют принудительное ограничение уникальности или уникальный индекс,

как это говорилось в Главах 17 и 18.

* когда вы используете одну или более агрегатных функций и не исполь-

зуете GROUP BY.

* когда вы используете SELECT DISTINCT во внешнем ключе с пре-

дикатом ссылающимся на единственное значение родительского ключа

(обеспечивая вашей системе предписание справочной целостность),

как в следующем примере:

EXEC SQL SELECT DISTINCT snum

Into :salesnum

FROM Customers

WHERE snum =

(SELECT snum

FROM Salespeople

WHERE sname = 'Motika');

Предпологалось что Salespeople.sname и Salespeople.snum - это соответс-

твенно, уникальный и первичный ключи этой таблицы, а Customers.snum

- это внешний ключ ссылающийся на Salespeople.snum, и вы предполага-

ли что этот запрос произведет единственную строку.

Имеются другие случаи, когда вы можете знаете, что запрос должен про-

извести единственную строку вывода, но они мало известны и, в больши-

нстве случаев, вы основываетесь на том что ваши данные имеют целост-

ИСПОЛЬЗОВАНИЕ SQL С ДРУГИМ ЯЗЫКОМ (ВЛОЖЕННЫЙ SQL) 341

______________________________________________________________________

ность, которая не может быть предписана с помощью ограничений. Не

полагайтесь на это! Вы создаете программу которая, вероятно, будет ис-

пользоваться в течение некоторого времени, и лучше всего проиграть ее

чтобы быть гарантированным в будущем от возможных отказов. Во всяк-

ом случае, нет необходимости группировать запросы которые производут

одиночные строки, поскольку SELECT INTO - используется только для

удобства.

Как вы увидите, вы можете использовать запросы выводящие многочис-

ленные строки, используя курсор.

КУРСОР

Одна из сильных качеств SQL - это способность функционировать на всех

строках таблицы, чтобы встретить определенное условие как блок запись,

не зная сколько таких строк там может быть. Если десять строк удовлетво-

ряют предикату, то запрос может вывести все десять строк. Если десять

миллионов строк определены, все десять миллионов строк будут выведены.

Это несколько затруднительно, когда вы попробуете связать это с другими

языками. Как вы сможете назначать вывод запроса для переменных когда

вы не знаете как велик будет вывод ? Решение состоит в том, чтобы испо-

льзовать то, что называется - курсором.

Вы вероятно знакомы с курсором, как с мигающей черточкой, которая от-

мечает вашу позицию на экране компьютера. Вы можете рассматривать

SQL курсор как устройство, которое аналогично этому, отмечает ваше мес-

то в выводе запроса, хотя аналогия не полная.

Курсор - это вид переменной, которая связана с запросом. Значением эт-

ой переменной может быть каждая строка, которая выводится при запросе.

Подобно главным переменным, курсоры должны быть обьявлены прежде,

чем они будут использованы. Это делается командой DECLARE CURSOR,

следующим образом:

EXEC SQL DECLARE CURSOR Londonsales FOR

SELECT *

FROM Salespeople

WHERE city = 'London';

Запрос не выполнится немедленно; он - только определяется. Курсор не-

много напоминает представление, в котором курсор содержит запрос,

342 ПОНИМАНИЕ SQL

______________________________________________________________________

ГЛ. 25

а содержание курсора - напоминает любой вывод запроса, каждый раз

когда курсор становится открытым. Однако, в отличие от базовых таблиц

или представлений, строки курсора упорядочены: имеются первая, вторая...

... и последняя строка курсора. Этот порядок может быть произвольным

с явным управлением с помощью предложения ORDER BY в запросе, или

же по умолчанию следовать какому-то упорядочению определяемому инс-

трументально-определяемой схемой.

Когда вы находите точку в вашей программе в которой вы хотите выпол-

нить запрос, вы открываете курсор с помощью следующей команды:

EXEC SQL OPEN CURSOR Londonsales;

Значения в курсоре могут быть получены, когда вы выполняете именно

эту команду, но не предыдущую команду DECLARE и не последующую

команду FETСH. Затем, вы используете команду FETCH чтобы извлечь

вывод из этого запроса, по одной строке в каждый момент времени.

EXEC SQL FETCH Londonsales INTO :id_num,

:salesperson, :loc, :comm;

Это выражение переместит значения из первой выбраной строки, в

переменные. Другая команда FETCH выводет следующий набор значе-

ний. Идея состоит в том, чтобы поместить команду FETCH внутрь цикла,

так чтобы выбрав строку, вы могли переместив набор значений из этой

строки в переменные, возвращались обратно в цикл чтобы переместить

следующий набор значений в те же самые переменные.

Например, возможно вам нужно чтобы вывод выдавался по одной строке,

спрашивая каждый раз у пользователя, хочет ли он продолжить чтобы ув-

идеть следующую строку

Look_at_more:= True;

EXEC SQL OPEN CURSOR Londonsales;

while Look_at_more do

begin

EXEC SQL FETCH Londonsales

Соседние файлы в папке ПОНИМАНИЕ SQL