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

8.7. Скалярные выражения

Скалярные выражения в SQL, по существу, простые. Поэтому мы удовлетворимся спи­ском наиболее важных операторов, которые можно использовать в конструкциях таких выражений, и предложим несколько дополнительных замечаний для операторов case и cast, значение которых сразу, возможно, и не очевидно. Подчеркнем, что в таких выражениях также могут встречаться итоговые функции, поскольку они возвращают ска­лярный результат. Более того, табличные выражения, заключенные в скобки, могут быть также истолкованы как скалярные значения, если только они в результате вычис­ления сводятся к таблице с одной строкой и одним столбцом. Как указывалось ранее, эта возможность, которая была введена в SQL/92, представляет главное усовершенство­вание новой версии SQL по сравнению с первоначальным вариантом.

Вот список основных операторов в алфавитном порядке: арифметические операторы (+,-,*,/); BIT_LENGTH; CASE; CAST; CHARACTER_LENGTH; CURRENT_USER; LOWER; OCTET_LENGTH; POSITION; SESSION_USER; SUBSTRING; SYSTEM_USER;TRIM; UPPER; USER.

Ниже кратко описаны операторы case и cast.

Оператор CASE

Оператор case возвращает одно значение из указанного набора значений в зависимо­сти от определенных условий. Например:

CASE

WHEN S. STATUS < 5 THEN 'Обращаться в последнюю очередь'

WHEN S.STATUS < 10 THEN 'Сомнительный'

WHEN S.STATUS < 15 THEN 'He очень хороший'

WHEN S.STATUS < 20 THEN 'Посредственный'

WHEN S.STATUS < 25 THEN 'Приемлемый'

ELSE 'Хороший'

END

Оператор CAST

Оператор cast преобразует определенное скалярное значение к определенному скаляр­ному типу данных (возможно, к домену, определенному пользователем). Например:

CAST ( 'S8' AS S# )

Не все пары типов данных взаимно конвертируемы. Более подробно о том, какие преобразования допустимы и как именно они выполняются, можно узнать из [8.1].

8.8. Встроенный sql

Как отмечалось ранее, выражения SQL могут выполняться или интерактивно, или как часть прикладной программы (в этом случае выражения SQL физически встраиваются в исходный код программы, смешиваясь с выражениями базового языка). До сих пор последний случай не рассматривался и подразумевалось (где это имело значение), что язык используется интерактивно. Теперь рассмотрим встро­енный SQL.

Фундаментальный принцип, лежащий в основе встроенного SQL, который мы бу­дем называть двухрежимным принципом, заключается в том, что любое выражение SQL, которое можно использовать интерактивно, можно также использовать и в прикладной программе. Конечно, существует множество различий в деталях между интерактивными и встроенными выражениями SQL, а операции выборки, в частности, требуют определенной внутренней обработки в среде базового языка; но, несмотря на это, двухрежимный принцип всегда верен. (Обратное, между прочим, не верно, т.е. существует несколько операторов встроенного SQL, которые не могут ис­пользоваться интерактивно, как мы вскоре убедимся.)

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

Прежде чем начать обсуждение конкретных операторов встроенного SQL, необ­ходимо рассмотреть некоторые предварительные детали. Большинство из них иллю­стрируется программным фрагментом на рис. 8.3. (Для констатации наших представ­лений будем считать, что базовым языком является PL/I. Большинство представле­ний транслируется на другие базовые языки лишь с незначительными изменениями.)

ЕХЕС SQL BEGIN DECLARE SECTION ;

DCL SQLSTATE CHAR(5) ;

DCL P# CHAR(6) ;

DCL WEIGHT FIXED DECIMAL(3) ;

ЕХЕС SQL END DECLARE SECTION ;

P# = 'P2' ; /*например*/

EXEC SQL SELECT P.WEIGHT

INTO :WEIGHT

FROM P

WHERE P.P# = :P# ;

IF SQLSTATE = '00000'

THEN ... ; /* WEIGHT (ВЕС) = выбираемому значению */

ELSE ... ; /* возникла какая-то исключительная ситуация */

Рис. 8.3. Фрагмент программыPL/1 с встроенным языком SQL

Рассмотрим все по порядку.

1. Операторы встроенного SQL предваряются инструкцией ЕХЕС SQL, так что их легко отличить от других операторов базового языка, и заканчиваются специаль­ным завершающим символом (точка с запятой ";" для PL/1).

2. Выполняемый оператор SQL (здесь и далее термин "встроенный" будет обычно опускаться) может быть в программе везде, где могут быть выполняемые базовые операторы. Обратите внимание на уточнение "выполняемые": в отличие от инте­рактивного SQL, встроенный SQL включает отдельные операторы, которые явля­ются чисто декларативными, а не выполняемыми. Например, оператор declare cursor— не выполняемый оператор, таковыми не являются и операторы begin, end, declare section, а также whenever (см. ниже).

3. Операторы SQL могут включать ссылки на базовые переменные (т.е. перемен­ные встроенного, или базового, языка); такие ссылки должны включать префикс в виде двоеточия для отделения их от имен столбцов SQL.

Базовые переменные могут использоваться во встроенном языке SQL (но только в операторах DML) везде, где могут использоваться литералы в интерактивном язы­ке SQL. Они могут также находиться в инструкции into операторов select или fetch (см. ниже), обозначая результирующие переменные для выборки, и в опреде­ленных операторах "динамического SQL" (также см. ниже).

4. Обратите внимание на инструкцию into оператора select на рис. 8.3. Назначение этой инструкции (как только что отмечалось) — указать результирующие (целевые) переменные, в которые будут возвращены выбранные значения; i-я це­левая переменная, указанная в инструкции into, соответствует i-му значению, ко­торое будет выбрано, как указано в инструкции select.

5. Все базовые переменные, на которые будут ссылаться операторы SQL, должны быть определены в разделе описаний встроенного SQL, который ограничивает­ся операторами begin и end раздела описаний (declare section).

6. Каждая программа встроенного SQL должна включать базовую переменную, называемую sqlstate(/////) . После выполнения какого-либо оператора в такую переменную в программе возвращается код состояния; в частности, код состояния 00000 означает, что оператор выполнился успешно, а 02000- что оператор выполнился, но никаких данных, удовлетворяющих запрос, не было найдено. Таким образом, каждый оператор SQL в программе должен завершаться проверкой переменной sqlstate, а соответствующие действия должны предприни­маться, если значение не то, которое ожидалось. На практике, однако, такая про­верка обычно выполняется неявно.

//////Ранние версии SQL использовали переменную, называемую SQLCODE; переменная SQLSTATE бы­ла добавлена в SQL/92, а переменная SQLCODE теперь официально "осуждается", поскольку большинст­во ее значений (в отличие от SQLSTATE) определяется реализацией, вместо того чтобы быть предписан­ными стандартом./////

7. Базовые переменные должны иметь подходящие типы данных в соответствии с тем, как эти переменные используются. В частности, базовая переменная, исполь­зуемая в качестве целевой (например, для операции fetch), должна иметь тип дан­ных, совместимый с типом выражения, которое представляет значение, присваи­ваемое этой целевой переменной; точно так же, если базовая переменная служит источником (например, для операции update), она должна иметь тип данных, со­вместимый с типом SQL того столбца, которому присваивается значение этого ис­точника. Подобные замечания касаются также базовых переменных, используе­мых в сравнениях или в любых других скалярных выражениях. В официальном документе стандарта [8.1] подробно объясняется, что означает для двух типов быть совместимыми.

8. Базовые переменные для столбцов SQL должны иметь те же имена.

9. Как уже упоминалось, каждое выражение SQL в принципе должно сопровождать­ся проверкой возвращаемого значения sqlstate. Оператор whenever предназначен для упрощения этого процесса и имеет следующий синтаксис:

ЕХЕС SQL WHENEVER condition action terminator

Здесь terminator это завершающий символ, упомянутый в пункте 1, условие condition может принимать значения sqlerror (ошибка SQL) или not found (не найдено), а действие action — это либо оператор continue (продолжить), либо оператор go то (перейти к). Оператор whenever не является выполняемым; это про­сто директива для процессора языка SQL. Наличие в программе выражения “ whenever condition go то label” приведет к тому, что процессор вставит оператор "if condition go то label" после каждого встретившегося ему выполняемого опера­тора SQL, а вот по выражению "whenever condition continue" процессор не вставля­ет никаких операторов, следовательно, программист должен будет вставлять такие операторы вручную. Два условия определяются так:

NOT FOUND означает никаких данных не найдено

(SQLSTATE = 02000) SQLERROR означает возникла ошибка

(см. описание стандарта [8.1] для SQLSTATE)

Каждый оператор whenever, который процессор SQL встречает при последователь­ном сканировании текста программы (для определенного условия), отменяет пре­дыдущий (для этого условия).

Итак, для предварительного обсуждения достаточно. Ниже мы сосредоточимся на операторах языка обработки данных. Как уже отмечалось, большинство из них можно использовать непосредственным образом (т.е. с незначительными изменениями в синтаксисе). Однако операции выборки имеют специальную трактовку. Проблема со­стоит в том, что такие операторы выбирают не просто одну, а много строк (в общем случае), в то время как базовые языки обычно не приспособлены для обработки выборки более одной строки за один раз. Следовательно, необходимо обеспечить некоторого рода мост между уровнем выборки “множества-за-один-раз” в SQL и уровнем выборки “строки-за-один-раз” в базовом языке; и таким мостом являются курсоры. Курсор— это новый вид объекта SQL, который применяется только во встроенном SQL (так как в интерактивном SQL в нем нет необходимости). Он представляет собой такой вид указателя, который может быть использован для перемещения по набору строк, указывая поочередно на каждую из них и таким образом обеспечивая возможность адресации к этим строкам — к одной за один раз. Однако отложим подробности обсуждение курсоров до одного из следующих разделов и рассмотрим сначала такие операторы, для которых курсоры не требуются.

Операции, не использующие курсоров

Операторы обработки данных, для которых не требуется использовать курсоры, следующие:

• "единичный select",

• INSERT,

• UPDATE (кроме формы CURRENT),

• DELETE (кроме формы СURRENT).

Ниже приводятся примеры для каждого из этих операторов.

Соседние файлы в папке Дейтл Введ в БД