|
| ||||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||||
|
2008 г.
Базы данных. Вводный курсСергей КузнецовЛекция 17. Общая характеристика оператора SELECT и организация списка ссылок на таблицы в разделе FROM17.1. ВведениеВ этой и следующих трех лекциях рассматривается важнейший оператор языка SQL – оператор Несмотря на то, что язык SQL является полным языком баз данных, включающим множество разнообразных средств определения схемы, ограничения и поддержки целостности базы данных, поддержки администрирования, заполнения и модификации таблиц базы данных, поддержки разработки приложений и т. д., для подавляющего большинства пользователей этот язык остается языком запросов, т. е. языком, позволяющим формулировать произвольно сложные и точные декларативные запросы к базе данных. Как отмечалось в конце предыдущей лекции, структура стандарта языка SQL фактически не позволяет описать одну часть языка (в частности, средства запросов) в отрыве от других частей. Тем не менее, полагая, что средства выборки данных составляют наиболее интересную и практически значимую часть языка, мы выделили для их рассмотрения несколько отдельных лекций. Напомним, что в этом курсе мы ограничиваемся базовым подмножеством SQL:1999 и SQL:2003 («прямым SQL») и даже это подмножество описываем не в полном объеме стандарта. Кроме того, в данной лекции мы не будем точно придерживаться порядка введения понятий и синтаксических конструкций, принятого в стандарте языка. Мы начнем с некоторой общей картины, дающей представление об операторе выборки, а затем будем постепенно уточнять ее. 17.2. Скалярные выраженияСкалярное выражение115) – это выражение, вырабатывающее результат некоторого типа, специфицированного в стандарте. Скалярные выражения являются основой языка SQL, поскольку, хотя это реляционный язык, все условия, элементы списков выборки и т. д. базируются именно на скалярных выражениях. В SQL:1999 имеется несколько разновидностей скалярных выражений. К числу наиболее важных разновидностей относятся численные выражения; выражения со значениями-строками символов; выражения со значениями даты-времени; выражения со значениями-временными интервалами; булевские выражения. Мы не будем слишком глубоко вникать в тонкости, но тем не менее приведем некоторые базовые спецификации и пояснения. Прежде чем перейти к конкретным видам скалярных выражений, рассмотрим некоторые наиболее общие языковые конструкции, на которых эти выражения базируются. 17.2.1. Общие синтаксические правила построения скалярных выраженийВ SQL:2003 имеются девять разновидностей выражений в соответствии с девятью категориями типов данных, значения которых вырабатываются при вычислении выражения
value_expression ::=
numeric_value_expression
| string_value_expression
| datetime_value_expression
| interval_value_expression
| boolean_value_expression
| array_value_expression
| multiset_value_expression
| row_value_expression
| user_defined_value_expression
| reference_value_expression
Как уже отмечалось в начале этого раздела, мы ограничимся обсуждением первых пяти разновидностей выражений. В основе построения этих видов выражений лежит первичное выражение, определяемое следующим синтаксическим правилом:
value_expression_primary ::=
unsigned_value_specification
| column_reference
| set_function_specification
| scalar_subquery
| case_expression
| (value_expression)
| cast_specification
В пределах этого курса можно считать, что спецификация беззнакового значения ( 17.2.2. Численные выраженияЧисленное выражение – это выражение, значение которого относится к числовому типу данных. Вот формальный синтаксис численного выражения:
numeric_value_expression> ::= numeric_term
| numeric_value_expression + term
| numeric_value_expression – term
numeric_term ::= numeric_factor
| numeric_term * numeric_factor
| numeric_term / numeric_factor
numeric_factor ::= [ { + | – } ] numeric_primary
numeric_primary ::= value_expression_primary
| numeric_value_function
Следует обратить внимание на то, что в численных выражениях SQL первичная составляющая (
numeric_value_function ::=
POSITION (character_value_expression
IN character_value_expression)
|{CHAR_LENGTH | CHARACTER_LENGTH }
(string_value_expression)
| OCTET_LENGTH (string_value_expression)
| BIT_LENGTH (string_value_expression)
| EXTRACT ({ datetime_field | time_zone field }
FROM { datetime_value_expression
| interval_value_expression })
| CARDINALITY (array_value_expression
| multiset_value_expression)
| ABS (numeric_value_expression)
| MOD (numeric_value_expression)
Мы достаточно подробно обсуждали функции определения позиции и длины по отношению к символьным и битовым строкам при рассмотрении соответствующих типов данных; здесь приводится только уточненный синтаксис их вызова. Функция 17.2.3. Выражения, значениями которых являются символьные или битовые строкиВыражения символьных и битовых строк – это выражения, значениями которых являются символьные или битовые строки. Соответствующие конструкции определяются следующим синтаксисом: string_value_expression ::= character_value_expression | bit_value_expression character_value_expression ::= сoncatenation | character_factor concatenation ::= character_value_expression || character_factor character_factor ::= character_primary [ collate_clause ] character_primary ::= value_expression_primary | string_value_function bit_value_expression ::= bit_concatenation | bit_factor bit_concatenation ::= bit_value_expression || bit_primary bit_primary ::= value_expression_primary | string value function Если не вдаваться в тонкости, смысл выражений символьных и битовых строк понятен из описания синтаксиса: единственная применимая для построения выражений операция – это конкатенация, производящая «склейку» строк-операндов. Более важно то, что первичной составляющей выражения над строками может быть как первичное скалярное выражение (см. выше), так и вызов функций, возвращающих строчные значения. Репертуар и синтаксис вызова таких функций определяются следующими правилами:
string_value_function ::= character_value_function
| bit_value_function
character _value_function ::= SUBSTRING
(character _value_expression
FROM start_position
[ FOR string_length ])
| SUBSTRING (character _value_expression
SIMILAR character _value_expression
ESCAPE character_value_expression)
| { UPPER | LOWER }
(character_value_expression)
| CONVERT (character_value_expression
USING conversion_name)
| TRANSLATE (character_value_expression)
USING translation_name)
| TRIM ([ {LEADING | TRAILING | BOTH} ]
[ character_value_expression ]
[ character_value_expression ])
| OVERLAY (character_value_expression
PLACING character_value_expression
FROM start_position
[ FOR string_length ])
bit _value_function ::= SUBSTRING (bit_value_expression
FROM start_position
[ FOR string_length ])
start_position ::= numeric_value_expression
string length ::= numeric_value_expression
Основные полезные функции – выделение подстроки ( 17.2.4. Выражения даты-времениК выражениям даты-времени мы относим выражения, вырабатывающие значения типа дата-время и интервал. Выражения даты-времени определяются следующими синтаксическими правилами:
datetime_value_expression ::=
datetime_term
| interval_value_expression + datetime term
| datetime_value_expression + interval term
| datetime value expression – interval term
datetime_term ::= datetime_primary
[ AT { LOCAL | TIME ZONE interval_value_expression } ]
datetime_primary ::= value_expression_primary
| datetime_value_function
Как видно из описания синтаксиса, сами выражения строятся очень просто – на основе обычных арифметических операций. Снова более интересны первичные составляющие – вызовы функций, возвращающих значение дата-время. Эти вызовы определяются следующим синтаксисом: datetime_value_function ::= CURRENT_DATE | CURRENT_TIME [ (precision) ] | LOCALTIME [ (precision) ] | CURRENT_TIMESTAMP [ (precision) ] | LOCALTIMESTAMP [ (precision) ] Видимо, приведенные синтаксические правила не нуждаются в комментариях: можно получить текущую дату, а также текущее время с желаемой точностью. Отличие функций Синтаксис выражений со значениями типа интервал определяется следующими правилами:
interval_value_expression ::=
interval_term
| interval_value_expression + interval term
| interval_value_expression – interval term
| (datetime value expression – datetime term)
interval_qualifier
interval_term ::= interval_factor
| interval_term * numeric_factor
| interval_term / numeric_factor
| numeric_term * interval_factor
interval_factor ::= [ { + | – } ]
interval_primary [ <interval qualifier> ]
interval_primary ::= value_expression_primary
| interval_value_function
Как видно из приведенных правил, выражения со значениями типа интервал устроены очень просто; почти вся содержательная информация была приведена при обсуждении соответствующего типа данных. Стоит только заметить, что квалификатор интервала указывается для того, чтобы явно специфицировать единицу измерения интервала. Поддерживается только одна функция 17.2.5. Булевские выраженияК булевским выражениям относятся выражения, вырабатывающие значения булевского типа (напомним, что булевский тип языка SQL содержит три логических значения – boolean_value_expression ::= boolean_term | boolean_value_expression OR boolean_term boolean_term ::= boolean_factor | boolean_term AND boolean_factor boolean_factor ::= [ NOT ] boolean_test boolean_test ::= boolean_primary [ IS [ NOT ] truth_value ] truth_value ::= TRUE | FALSE | UNKNOWN boolean_primary ::= predicate | (boolean_value_expression) | value_expression_primary Выражения вычисляются слева направо с учетом приоритетов операций (наиболее высокий приоритет имеет унарная операция
17.2.6. Выражения с переключателемВыражения с переключателем в некотором смысле ортогональны рассмотренным выше видам выражений, поскольку разные выражения с переключателем могут вырабатывать значения разных типов в зависимости от типа данных элементов. Поскольку мы еще вообще не рассматривали этот вид выражений, обсудим их более подробно. Как обычно, начнем с синтаксиса:
case_expression ::= case_abbreviation
| case_specification
case_abbreviation ::= NULLIF (value_expression , value_expression)
| COALESCE (value_expression_comma_list)
case specification ::= simple_case | searched_case
simple_case ::= CASE value_expression simple_when_clause_list
[ ELSE value_expression ] END
searched_case ::= CASE searched_when_clause_list
[ ELSE value_expression ] END
simple_when_clause ::= WHEN value_expression
THEN value_expression
searched_when_clause ::= WHEN conditional_expression
THEN value_expression
Наиболее общим видом выражения с переключателем является выражение с поисковым переключателем ( В выражении с простым переключателем ( CASE CO WHEN WO1 THEN result1 WHEN WO2 THEN result2 . . . . . . . WHEN WOn THEN resultn ELSE result END эквивалентно выражению с поисковым переключателем CASE WHEN CO = WO1 THEN result1 WHEN CO = WO2 THEN result2 . . . . . . . WHEN CO = WOn THEN resultn ELSE result END Выражение CASE WHEN V1 = V2 THEN NULL ELSE V1 END. Выражение CASE WHEN V1 IS NOT NULL THEN V1 ELSE V2 END. Выражение CASE WHEN V1 IS NOT NULL THEN V1 ELSE COALESCE (V2,... n) END. 115 В стандарте языка SQL в качестве общего термина для обозначения таких выражений используется термин value expression . Однако в менее формальных публикациях обычно применяется более понятный термин scalar expression , для которого, вдобавок, существует адекватный русский эквивалент скалярное выражение. В этом курсе мы также предпочитаем использовать именно этот термин. 116 Другие варианты появляются во встраиваемом и динамическом SQL, а также расширении языка, предназначенного для написания кода хранимых процедур, триггеров, методов определяемых пользователями типов и т.д. В любом случае беззнаковое значение известно до начала компиляции любой содержащей его конструкции языка SQL. 117 Для набора типов
|
|
CITForum © 1997–2025