Скалярные выражения
Скалярное выражение - это выражение, вырабатывающее результат некоторого типа, специфицированного в стандарте. Скалярные выражения являются основой языка SQL/92, поскольку, хотя это реляционный язык, все условия, элементы списков выборки и т.д. базируются именно на скалярных выражениях. Заметим, что в SQL/89 не требовалось вводить такое отдельное понятие, поскольку единственным допустимым скалярным выражением было арифметическое (т.е. вырабатывающее число). В связи с расширением ассортимента типов и операций над их значениями, в SQL/92 появилось три разных вида скалярных выражения - численные, над строками и над временем и датами (и интервалами). Мы не будем слишком глубоко вникать в тонкости, но тем не менее, приведем некоторые базовые спецификации и пояснения.
Прежде, чем перейти к конкретным видам скалярных выражений, рассмотрим некоторые более общие языковые конструкции, на которых эти выражения базируются. (Мы опускаем обсуждение типов данных, считая, что материала, приведенного в предыдущем разделе, достаточно для понимания.)
Спецификация значения и спецификация цели
Эти конструкции служат для спецификации значений, не выбираемых из таблиц базы данных, а заданных пользователями. Общий синтаксис выглядит следующим образом:
<value specification> ::= <literal> |<general value specification> <unsigned value specification> ::= <unsigned literal> |<general value specification> <general value specification> ::= <parameter specification> |<dynamic parameter specification> |<variable specification> |USER |CURRENT_USER |SESSION_USER |SYSTEM_USER VALUE <simple value specification> ::= <parameter name> |<embedded variable name |<literal> <target specification> ::= <parameter specification> |<variable specification> <simple target specification> ::= <parameter name> <embedded variable name> <parameter specification> ::= & lt;parameter name> [ <indicator parameter> ] <indicator parameter> ::= [ INDICATOR ] <parameter name> <dynamic parameter specification> ::= <question mark> <variable specification> ::= <embedded variable name> [ <indicator variable> ] <indicator variable> ::= [ INDICATOR ] <embedded variable name>
Пояснения: Спецификация параметра идентифицирует параметр или параметр и индикаторный параметр в модуле (вернее, в процедуре модуля). Спецификация динамического параметра идентифицирует параметр динамически подготовленного оператора. Спецификация переменной идентифицирует переменную включающего языка или такую переменную и индикаторную переменную. Спецификация цели определяет параметр или переменную, которым может быть присвоено значение. Отрицательное значение индикаторных параметра или переменной в спецификации параметра или переменной соответственно означает, что параметр или переменная содержат неопределенное значение. Значение CURRENT_USER есть значение текущего идентификатора авторизации; SESSION_USER - значение идентификатора авторизации SQL-сессии; SYSTEM_USER - определяемая в реализации строка, представляющая пользователя операционной системы, который выполнил оператор SQL, в результате которого было вычислено значение SYSTEM_USER.
Спецификация явного преобразования типа или домена
В SQL/89 существуют только неявные преобразования типов (например, FLOAT к DOUBLE). Конечно, это не всегда удобно, недостаточно гибко и иногда чревато ошибками. В SQL/92 существует специальная конструкция CAST, с помощью которой можно явно преобразовывать типы в пределах допускаемых преобразований. Синтаксис конструкции следующий:
<cast specification> ::= CAST <left paren> <cast operand> AS <cast target> <right paren> <cast operand> ::= <value expression> |NULL <cast target> ::= <domain name> |<data type>
Пояснения. Примем следующие обозначения типов данных:
EN | - ExactNumeric; |
AN | - ApproximateNumeric; |
C | - Character (Fixed- orVariable-length); |
FC | - Fixed-lengthCharacter; |
VC | - Variable-lengthCharacter; |
B | - BitString (Fixed- orVariable-length); |
FB | - Fixed-lengthBitString; |
VB | - Variable-lengthBitString; |
D | - Date; |
T | - Time; |
TS | - Timestamp; |
YM | - Year-MonthInterval; |
DT | - Day-TimeInterval. |
SD | TD | ||||||||||
EN | AN | VC | FC | VB | FB | D | T | TS | YM | DT | |
EN | Да | Да | Да | Да | Нет | Нет | Нет | Нет | Нет | ? | ? |
AN | Да | Да | Да | Да | Нет | Нет | Нет | Нет | Нет | Нет | Нет |
C | Да | Да | ? | ? | Да | Да | Да | Да | Да | Да | Да |
B | Нет | Нет | Да | Да | Да | Да | Нет | Нет | Нет | Нет | Нет |
D | Нет | Нет | Да | Да | Нет | Нет | Да | Нет | Да | Нет | Нет |
T | Нет | Нет | Да | Да | Нет | Нет | Нет | Да | Да | Нет | Нет |
TS | Нет | Нет | Да | Да | Нет | Нет | Да | Да | Да | Нет | Нет |
YM | ? | Нет | Да | Да | Нет | Нет | Нет | Нет | Нет | Да | Нет |
DT | ? | Нет | Да | Да | Нет | Нет | Нет | Нет | Нет | Нет | Да |
Оговорки состоят в следующем:
- Если TD - интервал, и SD - тип точных чисел, то TD должен содержать единственное поле даты-времени;
- Если TD - тип точных чисел, и SD - интервал, то SD должен содержать единственное поле даты-времени;
- Если SD - тип символьных строк, и TD - тип символьных строк постоянной или переменной длины, то репертуар символов SD и TD должен быть одним и тем же.
Результатом применения оператора CAST к неопределенному значению является неопределенное значение. Для значений, отличных от неопределенных, в стандарте приводятся подробные правила выполнения преобразований, которые интуитивно ясны.
Выражение, вырабатывающее значение
Это общая форма скалярного выражения, включающая все возможные типы результирующих значений. Синтаксис следующий:
<value expression> ::= <numeric value expression> |<string value expression> |<datetime value expression> |<interval value expression> <value expression primary> ::= <unsigned value specification> |<column reference> |<set function specification> |<scalar subquery> |<case expression> |<left paren> |<value expression> |<right paren> |<cast specification>
Пояснения: При вычислении выражения V для строки таблицы каждая ссылка на столбец этой таблицы, непосредственно содержащаяся в V, рассматривается как ссылка на значение данного столбца в данной строке. Если первичное выражение есть скалярный подзапрос (подзапрос, результатом которого является таблица, состоящая из одной строки и одного столбца), и результат подзапроса пуст, то результатом первичного выражения является неопределенное значение.