Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
7_17_27_37_47_57_ответы.docx
Скачиваний:
2
Добавлен:
17.09.2019
Размер:
50 Кб
Скачать
  1. Значения по умолчанию

Иногда в момент создания или модификации кортежа значения некоторых его компонентов не известны. В примере 6.40 рассматривалась ситуация, связанная с до­бавлением в схему отношения нового атрибута. Если отношение уже содержит корте­жи, система не "знает" о том, какие конкретные значения следует присвоить вновь созданным компонентам этих кортежей, и предлагает воспользоваться значениями null. Аналогичная ситуация возникает и при выполнении команды вставки кортежа в отношение studio, когда известно только название киностудии, а ее адрес и серти­фикационный номер президента — нет (см. пример 6.35 на с. 292).

Для преодоления подобных проблем в SQL используется значение null, автоматиче­ски присваиваемое любому компоненту, точное значение которого в данный момент не известно, — за исключением некоторых ситуаций, когда null применять нельзя (см. раздел 7.1 на с. 318). Однако подчас было бы целесообразно предпочесть иное зна­чение, которое должно предлагаться системой по умолчанию (default value), если никакие другие значения, подходящие для присваивания конкретному компоненту, не известны.

Вообще говоря, любую инструкцию, в которой определяется название атрибута и его тип, можно сопроводить служебным словом default и соответствующим зна­чением. В качестве значения допустимо вводить null или какую-либо константу (в некоторых случаях система предлагает и иные варианты — например, значение текущего момента времени).

  1. Индексы

Индекс (index) атрибута А некоторого отношения R — это структура данных, позво ляющая повысить эффективность процедуры отыскания некоторого конкретного зна чения, хранимого в компонентах атрибута А. Наличие индекса обычно способно при

вести к существенному уменьшению времени обработки запросов, в которых значе­ния атрибута Л сравниваются с константами посредством выражений, таких, как, ска­жем, А = 3 или даже А < 3. Технологиям создания индексов для крупных отношений в процессе реализации СУБД отводится весьма важная роль.

57. Курсоры

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

1. Объявить курсор. Простейшая форма объявления курсора состоит из следую­щих частей:

  1. начального предложения exec sql, используемого для "внедрения" инст­рукций SQL в код базовой программы;

  2. служебного слова declare;

  3. наименования С курсора;

  4. пары служебных слов cursor for;

  5. выражения Q, представляющего собой наименование отношения или текст запроса вида "select—from—where", возвращающего отношение. Будучи объ­явленным и открытым (opened), курсор предоставляет возможность "перемещения" по кортежам отношения Q — после выполнения програм­мой инструкции извлечения (fetch) кортежа курсор будет содержать ссылку на текущий кортеж отношения.

Иными словами, выражение объявления курсора можно представить так: exec sql declare С cursor for Q;

    1. Открыть курсор. Инструкция открытия курсора С выглядит следующим образом:

exec sql open с;

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

    1. Выполнить одну или несколько команд извлечения (fetch) кортежа. Назначение команды состоит в получении очередного кортежа отношения, которое указано в объявлении курсора. Если на некотором шаге множество кортежей оказывает­ся исчерпанным, т.е. команда извлечения не способна возвратить очередной кортеж, в переменную sqlstate заносится код '02 000', означающий, что "кортеж не найден". Команда извлечения кортежа состоит из следующих частей:

      1. служебных слов exec sql fetch from;

      2. наименования С курсора;

      3. служебного слова into;

      4. списка L общих переменных. Если кортеж, подлежащий извлечению, суще­ствует, содержимое компонентов кортежа присваивается переменным в со­ответствии с порядком следования их в списке.

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

exec sql fetch from С into L\

4. Закрыть курсор. Инструкция закрытия курсора С выглядит следующим образом:

exec sql close с;

После закрытия курсор не способен реагировать на команды извлечения кор­тежей.

  1. Модификация данных посредством курсоров

Если курсор открыт для базовой таблицы {а не для виртуальной таблицы либо от­ношения, возвращаемого в результате обработки запроса), с его помощью вполне до­пустимо не только считывать и обрабатывать содержимое кортежей, но и удалять (delete) или обновлять (update) их.. Единственное исключение связано с конст­рукцией предложения where. При использовании команд модификации в контексте курсора предложение where принимает вид

where current of С

где С — наименование курсора.

  1. Защита данных курсора от внешних воздействий

Предположим, что во время выполнения функции worthRanges, вычисляющей распределение значений доходов руководящих лиц, некоторый другой процесс, протекающий параллельно, модифицирует содержимое того же отно­шения MovieExec. Давайте примем следующую ситуацию как должное: существует некий "сторонний" процесс, пытающийся модифицировать отношение в тот момент, когда наша программа использует данные этого отношения для собственных нужд.

Что можно предпринять в подобном случае? Как кажется, почти ничего. Получиї статистические данные, мы, вероятно, будем пребывать в счастливом неведении, даже не догадываясь о том, что некоторые кортежи, которые, как мы полагаем, наша про­грамма с успехом обработала, на самом деле были удалены другим приложением. Hf первый взгляд, остается просто доверять той информации, которую способен возвра­тить созданный нами курсор.

8.1.9. Изменение порядка просмотра содержимого курсора

Курсор может быть снабжен механизмом, позволяющим выбирать способ "перемещения" по кортежам отношения, лежащего в основе определения курсора. По умолчанию (и это удобно в большинстве ситуаций) система предлагает начать про­смотр содержимого курсора с первого кортежа и извлекать кортежи в естественном порядке их следования, вплоть до достижения завершающего кортежа. В некоторых ситуациях требуется изменять порядок обработки либо на протяжении сеанса откры­тия курсора обращаться к одним и тем кортежам несколько раз.48 Чтобы воспользо­ваться подобными возможностями, надлежит выполнить два действия.

    1. Включить в конструкцию объявления курсора (непосредственно перед словом cursor) служебное слово scroll, свидетельствующее о том, что курсор должен позволять "пролистывание" его содержимого в произвольном порядке, отлич­ном от линейного, предлагаемого по умолчанию.

    2. Сопроводить служебное слово FETCH в одноименной команде одним из пере­численных ниже слов, соответствующих требуемому режиму "перемещения" внутри курсора:

      1. next или prior — для перемещения соответственно к следующему или пре­дыдущему кортежу относительно текущего; если ни одно из служебных слов, указывающих "направление" перемещения, не задано, по умолчанию, как наиболее уместный, подразумевается режим next;

      2. first или last — для перемещения соответственно к первому или послед­нему кортежу;

      3. relative п (где п — целое значение) — для перемещения на п позиций впе­ред (если п положительно) или на п позиций назад (если п отрицательно)

относительно текущего кортежа; например, relative і — это синоним next, a relative — синоним prior;

d) absolute п (где п — целое значение) — для перемещения на п позиций вперед, начиная с нулевой (если п положительно), или на п позиций назад, начиная с позиции, следующей за завершающим кортежем (если п отрицательно); на­пример, absolute 1 — это синоним first, a absolute — синоним last.

57. Динамический SQL

До сих пор, говоря о "внедрении" команд SQL в код программы, написанной на базовом языке, мы полагали, что текст SQL известен заранее. Альтернативный под­ход, более гибкий и многообещающий, предусматривает, что

EXEC SQL FETCH LAST FROM execCursor INTO :execName, :execAddr, :certNo, : worth. ;

while{1} {

/* Те же строки 10-14 */

EXEC SQL FETCH PRIOR FROM execCursor INTO :execName, :execAddr, :certNo, :worth;

}

Рис. 8.6. Пример процедуры просмотра кортежей в "обратном" порядке

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

Примером подобной программы может служить приложение, которое запраши­вает текст команды SQL у пользователя, а затем считывает и выполняет ее. На про­тяжении главы 6 (см. с. 249~316)мы подразумевали именно такой режим работы: многие коммерческие СУБД содержат в своем составе приложения, позволяющие вводить и выполнять произвольные команды SQL. Команда, введенная пользовате­лем, подлежит синтаксическому анализу, а затем система выбирает наиболее целе­сообразный способ ее выполнения.

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

        1. EXEC SQL PREPARE V FROM E, где V~ переменная SQL, a E — общая пере­менная или выражение строкового типа. Выражение Е считывается и анализи­руется (подготавливается — prepare), но не выполняется: найденный системой план (plan) выполнения присваивается переменной V.

        2. exec SQL execute V. Содержимое переменной V трактуется как команда SQL и выполняется.

Обе стадии можно объединить в одну, если воспользоваться директивой

EXEC SQL EXECUTE IMMEDIATE Е

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

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]