2. SQL РЕД Базы Данных. Общие сведения

В реляционной базе данных хранятся собственно обрабатываемые клиентскими программами данные и метаданные — описания этих данных. Для работы как с данными, так и с метаданными используется язык SQL (Structured Query Language) - структурированный язык запросов.

В реляционных базах данных все данные хранятся в таблицах. Это один из основных объектов базы данных. Метаданные, описания объектов реляционной базы данных, также хранятся в таблицах, в системных таблицах.

Базы данных используются для решения задач в конкретных областях человеческой деятельности. Это могут быть, например, задачи любого весьма сложного информационного поиска, расчета заработной платы, выплат в бюджеты разных уровней и т.д.

2.1. Структура данных на внешнем носителе (ODS)

С точки зрения операционной системы база данных — это файл или группа файлов, хранящихся на внешних носителях. Файл базы данных в РЕД Базе Данных имеет страничную довольно сложную организацию.

В разных версиях РЕД Базы Данных используются различные форматы хранения данных на внешних носителях. Такие форматы называются ODS (On-Disk Structure — структура данных на диске). Форматам присваиваются номера. В настоящей версии РЕД Базы Данных используется ODS версии 13.0. Узнать версию ODS можно с помощью gstat -h.

Таблица 2.1 Соответствие версий ODS версиям РЕД Базы Данных

Версия СУБД

Версия ODS

РЕД База Данных 5.0.0

13.1

РЕД База Данных 3.0.8 - РЕД База Данных 3.0.10

12.3

РЕД База Данных 3.0.0 - РЕД База Данных 3.0.7

12.0

РЕД База Данных 2.6

2.4

РЕД База Данных 2.5

24578.3

РЕД База Данных 2.1

24578.2

РЕД База Данных 2.0

11.0

Как правило, не существует полной обратной совместимости более поздней версии ODS с более ранней. Чтобы перевести существующую базу данных с более ранней ODS в текущую необходимо выполнить резервное копирование базы данных с использованием соответствующего средства предыдущей версии (обычно это утилита командной строки gbak), а затем восстановить резервную копию в текущей версии РЕД Базы Данных. Обновить базу данных до последней минорной версии ODS в пределах поддерживаемой мажорной версии можно командой gfix -upgrade.

2.2. Объекты базы данных

Объектами базы данных в СУБД РЕД База Данных являются следующие.

Таблица (table)

Это основной объект любой реляционной базы данных, в том числе, и РЕД Базы Данных. В таблицах хранятся все данные и метаданные базы данных. Таблица — это плоская двумерная структура, содержащая произвольное количество строк (row). Часто строку называют записью (record). Таблица может не содержать и ни одной строки — может быть пустой. Все строки одной таблицы имеют одинаковую структуру. Они состоят из столбцов (column). Другое название для столбца — поле (field). Таблица в реляционной базе данных должна содержать хотя бы один столбец. Каждый столбец имеет конкретный тип данных (datatype). Подробнее о типах данных РЕД Базы Данных см. в главе 4. О создании и изменении таблиц см. в главе 10.

Домен (domain)

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

Индекс (index)

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

Генератор (generator или sequence)

Простой объект реляционной базы данных, предназначенный для получения уникального числового значения, используемого, как правило, для формирования значения искусственного первичного ключа или иногда уникального ключа. Использование генераторов подробно описано в главе 13.

Хранимая процедура (stored procedure)

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

Хранимые процедуры могут получать от вызывающей программы (хранимой процедуры, клиентской программы, триггера) параметры и возвращать произвольное количество значений. Существуют хранимые процедуры выбора, осуществляющие выбор данных из таблиц базы данных (к таким процедурам можно обращаться как и к обычным таблицам в операторе SELECT), и выполняемые хранимые процедуры, осуществляющие любые действия с данными. Использование хранимых процедур см. в главе 19. В РЕД Базе Данных также существуют дополнительные расширения языка хранимых процедур с добавлением элементов языка Java. Подробности см. в главе 25.

Хранимая функция (stored function)

Программа, написанная на процедурном расширении языка SQL (который также называется языком хранимых процедур и триггеров, PSQL), и хранящаяся в области метаданных базы данных и выполняющаяся на стороне сервера. К хранимой функции могут обращаться хранимые процедуры, хранимые функции (в том числе и сама к себе), триггеры и клиентские программы. При обращении хранимой функции самой к себе такая хранимая функция называется рекурсивной. В отличие от хранимых процедур хранимые функции всегда возвращают одно скалярное значение. Использование хранимых функций см. в главе 20.

Триггер (trigger)

Как и хранимая процедура является программой, написанной на процедурном расширении языка PSQL, хранящейся в области метаданных и выполняемой на сервере. Однако обращение напрямую к триггеру невозможно. Он автоматически вызывается при наступлении одной из фаз события, связанного с изменением данных в таблицах, или события, связанного с подключением к базе данных и с работой с транзакциями. События таблицы — добавление данных, изменение строки таблицы, удаление строки. Фазами являются «до» (before) — до выполнения действия — и «после» (after) — после выполнения действия. В РЕД Базе Данных один и тот же триггер может вызываться при наступлении одной из фаз сразу нескольких событий. Возможны пять вариантов вызова триггера, которые связаны с процессом подключения к базе данных и с работой с транзакциями. Подробности об использовании триггеров см. в главе 21.

Пакет (package)

Группа процедур и функций, которая представляет собой единый объект базы данных. Пакеты упрощают механизм отслеживания зависимостей между набором связанных процедур, а также между этим набором и другими процедурами, как упакованными, так и неупакованными. Подробности об использовании пакетов см. в главе 22.

Пользовательские исключения (exception)

Объект реляционной базы данных, который позволяет создавать, а затем выдавать сообщения пользователю при появлении некоторой ситуации в процессе работы программ с базой данных. Это могут быть как ошибочные ситуации, возникающие при каких-либо нарушениях в базе данных, так и любые другие особые случаи обработки данных в базе данных. Эти исключения могут использоваться только в хранимых процедурах и триггерах. Пользовательские исключения описываются в главе 17 и в разделе 18.5.

События базы данных (event)

В РЕД Базе Данных существует возможность из хранимых процедур и триггеров передавать некоторые сообщения всем клиентским приложениям, работающим с конкретной базой данных и «прослушивающим» данное сообщение. Это средство позволяет во многих случаях осуществлять синхронизацию отображения данных либо выполнять более сложные действия по взаимодействию клиентских приложений при их совместной одновременной работе с базой данных. События базы данных описываются в главе 18.

Представление (view)

Другие названия — обзор, просмотр. Это результат выборки данных из одной или более таблиц базы данных на основании конкретных часто довольно сложных критериев. Основой представления является оператор SELECT любой сложности. Представление является как бы виртуальной таблицей, которая на самом деле не хранится в базе данных. Представление — удобное средство для получения данных в случае достаточно сложной выборки данных, когда от пользователя нужно скрывать сложные условия такой выборки. Кроме того, представления являются полезным средством скрыть от пользователя некоторые столбцы таблиц, значения которых не предназначены для просмотра этим пользователем. Представления описаны в главе 16.

Функции, определенные пользователем (User Defined Functions, UDF)

Примечание

Поддержка внешних UDF функций (реализованных в динамических библиотеках и определенных в базе данных с помощью функций оператора DECLARE EXTERNAL FUNCTION) в версии 5.0 устарела.

Функции, написанные на любом языке программирования, и хранящиеся вне базы данных, но описанные в этой базе. Могут использоваться для расширения возможностей языка SQL и соответствующих языков программирования. Часто позволяют описывать довольно сложные действия с данными из базы данных (или с данными, передаваемыми в виде входных параметров). В РЕД Базе Данных представлено достаточно большое количество полезных функций, созданных разработчиками системы. Подробности описания в базе данных и использования UDF см. 34.

Транзакция (transaction)

Это не объект базы данных, а некоторый механизм, используемый при обращении к данным или метаданным базы данных. Любые действия с данными (и метаданными) в базе данных выполняются в контексте (под управлением) какой-либо транзакции. В процессе «жизни» транзакции действия с данными базы данных, выполненные под управлением этой транзакции до ее подтверждения, не видны другим параллельным процессам. Все действия, выполненные в контексте транзакции, можно либо подтвердить (тогда изменения становятся видимыми в других параллельных процессах) или отменить, выполнить откат транзакции (тогда база данных возвращается в то состояние, которое она имела до старта этой транзакции). Существуют средства использовать вложенные транзакции, когда создаются определенные контрольные точки, и откат транзакции можно выполнить не на самое начало транзакции, а на определенную контрольную точку.

В РЕД Базе Данных используется многоверсионная архитектура (Multigenerational architecture, MDA). При такой архитектуре в результате добавления, изменения или удаления отдельных записей создаются новые версии этих записей. Благодаря этой архитектуре другие пользователи могут видеть и использовать предыдущие версии записи, даже если она была изменена или удалена в текущей транзакции.

Транзакциям посвящена глава 6.

2.3. Подмножества языка

В SQL РЕД Базы Данных выделяются следующие подмножества, подразделы языка.

Язык описания данных — DDL, Data Definition Language. При помощи этого подмножества языка создаются, изменяются и удаляются объекты базы данных, метаданные. Для создания нового экземпляра любого объекта базы данных используется оператор CREATE, для изменения — ALTER, для удаления — DROP.

Язык манипулирования данными — DML, Data Manipulation Language. Средства этого подмножества используются для изменения и выборки данных, хранящихся в базе данных, а также для запуска, подтверждения или отката транзакций. Для добавления новых данных (новых строк) в таблицы используется оператор INSERT, для изменения существующих данных — UPDATE, для удаления — DELETE, для выборки данных — SELECT. Для старта, запуска, транзакции используется оператор SET TRANSACTION, для ее подтверждения COMMIT, для отката транзакции — ROLLBACK.

Основная особенность языка SQL — его декларативность. При помощи большинства языковых средств пользователь задает, что должно быть сделано, но не указывает, как это должно быть выполнено. В подмножестве DML можно выделить декларативное ядро — языковые средства, используемые в любых ситуациях.

Существует также императивное расширение языковых средств DML, называемое процедурным SQL (PSQL) или языком хранимых процедур и триггеров. Оба термина являются синонимами. Это расширение содержит операцию присваивания, условные операторы, операторы циклов, средства обработки ошибок базы данных, выдачи исключений, отправки сообщений (событий) другим клиентским программам, работающим в настоящий момент с этой базой данных, контекстные переменные NEW, OLD, и некоторые другие средства, используемые в обычных языках программирования. Язык хранимых процедур и триггеров подробно описывается в главе 18.

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

2.4. Диалекты базы данных

В СУБД РЕД База Данных существует понятие диалекта базы данных. Каждый клиент, соединенный с базой данных, и каждая база данных имеют свой диалект SQL. Диалект определяет допустимость некоторых синтаксических конструкций в SQL, интерпретацию отдельных синтаксических конструкций и способ хранения столбцов различных типов данных на внешних носителях.

В РЕД Базе Данных поддерживается и диалект 1, который присутствовал в базах данных InterBase версии 5.6 и более ранних.

Основным диалектом в настоящее время является диалект 3, который более всего соответствует стандартам SQL и более удобен в работе. Новую базу данных СУБД РЕД База Данных создаёт в 3-м диалекте.

Для задания диалекта клиента используется оператор SET SQL DIALECT. Его синтаксис:

SET SQL DIALECT {1 | 3};

Установленный для клиента диалект присваивается создаваемой этим клиентом новой базе данных.

Основные отличия диалектов 1 и 3 приведены в таблице 2.2:

Таблица 2.2 Отличия диалектов 1 и 3

Средство

Диалект 1

Диалект 3

Имена с разделителями, заключенные в кавычки "

Рассматриваются как символьные константы

Рассматриваются как идентификаторы, которые являются зависимыми от регистра

Тип данных DATE

Занимает 8 байтов. Содержит дату и время

Занимает 4 байта. Содержит только дату

Тип данных TIMESTAMP

Не используется

Занимает 8 байтов. Содержит дату и время

Типы данных NUMERIC и DECIMAL, размер 1 ÷ 4

NUMERIC хранится как SMALLINT,

DECIMAL — как INTEGER

Оба хранятся как SMALLINT

Типы данных NUMERIC и DECIMAL, размер 5 ÷ 9

Хранятся как INTEGER

Хранятся как INTEGER

Типы данных NUMERIC и DECIMAL, размер 10 ÷ 18

Хранятся как DOUBLE PRECISION

Хранятся как BIGINT

Тип данных BIGINT

Недоступен

Доступен в качестве целого 64-х битного типа данных

Генераторы

Значение генераторов хранится как 64 битное целое, а при выдаче значения усекается до 32 битного целого

Значения генераторов хранятся как 64-ти битные целые значения

Существует еще диалект 2. Он применим только на стороне клиента. Этот диалект может быть использован лишь для проверки возможности миграции данных из более раннего диалекта 1 в диалект 3. В случае возможных ошибок выдается предупреждающее сообщение.

В настоящем документе при описании синтаксических конструкций используется только SQL диалекта 3.

2.5. Операторы. Общие сведения

Основная конструкция SQL — оператор (statement). Оператор описывает, что должна выполнить система управления базами данных с конкретным объектом данных или метаданных, обычно не указывая, как именно это должно быть выполнено. Достаточно сложные операторы содержат более простые конструкции — предложения (clause) и варианты, альтернативы. Предложение описывает некую законченную конструкцию в операторе. Например, предложение WHERE в операторе SELECT и в ряде других операторов (UPDATE, DELETE) задает условия поиска данных в таблице (таблицах), подлежащих выборке, изменению, удалению. Предложение ORDER BY задает характеристики упорядочения выходного, результирующего, набора данных. Альтернативы, будучи наиболее простыми конструкциями, задаются при помощи конкретных ключевых слов и определяют некоторые дополнительные характеристики элементов предложения (допустимость дублирования данных, варианты использования и др.).

2.6. Ключевые слова. Общие сведения

В SQL существуют ключевые слова и зарезервированные слова. Ключевые слова — это все слова, входящие в лексику (словарь) языка SQL. Ключевые слова можно использовать и в качестве имен, идентификаторов, объектов базы данных, внутренних переменных и параметров. Зарезервированные слова — это те ключевые слова, которые нельзя использовать в качестве имен объектов базы данных, переменных или параметров.

Список зарезервированных и ключевых слов представлен в 29.

2.7. Идентификаторы

Все объекты базы данных имеют имена, которые иногда называют идентификаторами. Максимальная длина идентификатора составляет 63 символа. Существует два типа имен — имена, похожие по форме на имена переменных в обычных языках программирования, и имена с разделителями (delimited name), которые являются отличительной особенностью языка SQL.

Обычное имя должно начинаться с буквы латинского алфавита, за которой могут следовать буквы (латинского алфавита), цифры, символ подчеркивания и знак доллара. Такое имя нечувствительно к регистру, его можно записывать как строчными, так и прописными буквами. В имени нельзя использовать буквы кириллицы, пробелы, другие специальные символы.

Листинг 2.1 Синтаксис идентификаторов

<имя> ::= <буква> | <имя><буква> | <имя><цифра> | <имя>_ | <имя>$

<буква> ::= <прописная буква> | <строчная буква>

<прописная буква> ::= A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z

<строчная буква> ::= a | b | c | d | e | f | g | h | i | j | k | l | m | n | o | p | q | r | s | t | u | v | w | x | y | z

<цифра> ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9

Следующие имена с точки зрения системы являются одинаковыми:

fullname       FULLNAME       FuLlNaMe       FullName

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

Синтаксис имени с разделителями:

Листинг 2.2 Синтаксис идентификаторов

<имя с разделителями> ::= "<символ ASCII>[<символ ASCII>...]"

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

Существует определенная похожесть и отличие обычных имен и имен с разделителями. Такие имена с разделителями и обычные, как "FULLNAME" и FULLNAME являются одинаковыми, а "FullName" и FULLNAME (так же как, например, и FullName) отличаются.

2.8. Константы (литералы)

Литералы служат для непосредственного представления данных. Константа — это значение, подставляемое непосредственно в SQL оператор, которое не получено из выражения, параметра, ссылки на столбец или переменной. Константой может быть строка или число. Ниже приведён список стандартных литералов:

Литералы

Примеры

Целочисленные

0, -34, 45, 0X080000000

Вещественные

0.0, -3.14, 3.23e-23

Строковые

'текст', 'don''t!'

Дата

DATE '10.01.2014'

Время

TIME '15:12:56'

Временная отметка

TIMESTAMP '10.01.2014 13:32:02'

Неопределённое состояние

null

Строковые константы

Строковая константа это последовательность символов, заключенных между парой апострофов («одинарных кавычек»). Максимальная длина строковой константы составляет 65535 байт; максимальная количество символов будет определяться количеством байт, используемых для кодирования каждого символа.

Примечание

Двойные кавычки не должны (допускаются 1 диалектом) использоваться для квотирования строк. В SQL они предусмотрены для других целей.

Если литерал апострофа требуется в строковой константе, то он может быть «экранирован» другим предшествующим апострофом:

'Mother O''Reilly''s home-made hooch'

Вместо двойного апострофа можно использовать другой символ или пару символов. Ключевое слово q или Q предшествующее строке в кавычках сообщает парсеру, что некоторые левые и правые пары одинаковых символов являются разделителями для встроенного строкового литерала.

<строковая константа> ::=
                {q|Q}'<символ начала строки> [<символ>...] <символ конца строки>'

Символ конца строки должен совпадать с символом начала строки, за исключением символов '('-')', '{'-'}', '['-']' и '<'-'>', которые нужно использовать с паре. Внутри строки можно ставить одинарные кавычки.

SELECT Q'{abc{def}ghi}' FROM rdb$database;          -- abc{def}ghi
SELECT q'!That's a string!' FROM rdb$database;      -- That's a string

Необходимо быть осторожным с длиной строки, если значение должно быть записано в столбец типа VARCHAR. Максимальная длина строки для типа VARCHAR составляет 32765 байт (32767 для типа CHAR). Если значение должно быть записано в столбец типа BLOB, то максимальная длина строкового литерала составляет 65535 байт.

Предполагается, что набор символов строковой константы совпадает с набором символов столбца предназначенного для её сохранения.

При необходимости, строковому литералу может предшествовать имя набор символов, который начинается с префикса подчеркивания «_». Это известно как вводный синтаксис (Introducer syntax). Его цель заключается в информировании РЕД Базы Данных о том, как интерпретировать и хранить входящую строку.

INSERT INTO People VALUES (_ISO8859_1 'Hans-Jörg Schäfer');

Строковые константы могут быть записаны в шестнадцатеричной нотации, так называемые «двоичные строки». Каждая пара шестнадцатеричных цифр определяет один байт в строке. Строки введённые таким образом будут иметь кодировку OCTETS по умолчанию, но вводный синтаксис (introducer syntax) может быть использован для принудительной интерпретации строки в другом наборе символов.

Листинг 2.3 Синтаксис двоичных строк

{x|X}'<шестнадцатеричная строка>'

<шестнадцатеричная строка> ::= четное количество <шестнадцатеричных цифр>

<шестнадцатеричная цифра> ::= 0..9 | A..F | a..f
SELECT x'4E657276656E' FROM rdb$database;    -- 4E657276656E  (6-byte 'binary' string)

SELECT _ascii x'4E657276656E' FROM rdb$database;   -- Nerven  (same string, now inter-
                                                               preted as ASCII text)
SELECT _iso8859_1 x'53C3A46765' FROM rdb$database; -- Säge  (4 chars, 4 bytes)

SELECT _utf8 x'53C3A46765' FROM rdb$database;      -- Säge  (4 chars, 5 bytes)

Примечание

Как будут отображены двоичные строки зависит от интерфейса клиента. Например, утилита isql использует заглавные буквы A-F, в то время как FlameRobin буквы в нижнем регистре. Другие могут использовать другие правила конвертирования, например отображать пробелы между парами байт: '4E 65 72 76 65 6E'.

Примечание

Шестнадцатеричная нотация позволяет вставить любой байт (включая 00) в любой позиции в строке.

Числовые константы

Числовая константа — это любое правильное число в одной из поддерживаемых нотаций:

  • В SQL, для чисел в стандартной десятичной записи, десятичная точка всегда представлена символом точки и тысячи не разделены. Использование запятых, пробелов, и т.д. вызовет ошибки.

  • Экспоненциальная запись, например число 0.0000234 может быть записано как 2.34e-5. Латинская буква E (равно как и e) означает, что после нее указывается порядок числа — целое число со знаком, задающее степень числа 10. Если целая часть в мантиссе числа отсутствует, то символ нуля, как и в большинстве языков программирования, можно не указывать.

  • Запись чисел в двоичном, восьмеричном и шестнадцатеричном формате.

  • В числовых литералах можно использовать подчёркивание ("_").

Синтаксис числовых констант:

<числовой литерал со знаком> ::=
       [ <знак> ] <беззнаковый числовой литерал>

<беззнаковый числовой литерал> ::=
       <точная запись числа>
     | <экспоненциальная запись>

<точная запись числа> ::=
       <беззнаковое целое число>
     | <беззнаковое десятичное целое число>.[ <беззнаковое десятичное целое число> ]
     | .<беззнаковое десятичное целое число>

<знак> ::=
       <знак плюс>
     | <знак минус>

<экспоненциальная запись> ::= <мантисса> E <экспонента>

<мантисса> ::= <точная запись числа>

<экспонента> ::= <десятичное целое число со знаком>

<десятичное целое число со знаком> ::= [ <знак> ] <беззнаковое десятичное целое число>

<целое число со знаком> ::= [ <знак> ] <беззнаковое целое число>

<беззнаковое целое число> ::=
       <беззнаковое десятичное целое число>
     | <беззнаковое шестнадцатеричное целое число>
     | <беззнаковое восьмеричное целое число>
     | <беззнаковое двоичное целое число>

<беззнаковое десятичное целое число> ::=
       <цифра> [ { [<подчёркивание>] <цифра> }... ]

<беззнаковое шестнадцатеричное целое число> ::=
       0X { [<подчёркивание>] <шестнадцатеричная цифра> }...

<беззнаковое восьмеричное целое число> ::=
       0O { [<подчёркивание>] <восьмеричная цифра> }...

<беззнаковое двоичное целое число> ::=
       0B { [<подчёркивание>] <двоичная цифра> }

<знак плюс> ::= + | U+002B

<знак минус> ::= - | U+002D

<точка> ::= . | U+002E

<подчёркивание> ::= _ | U+005F

<шестнадцатеричная цифра> ::=
       0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
     | A | B | C | D | E | F | a | b | c | d | e | f

<десятичная цифра> ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9

<восьмеричная цифра> ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7

<двоичная цифра> ::= 0 | 1

В числовых литералах допускаются подчёркивания (например, для наглядной записи больших чисел). Символ нижнего подчеркивания игнорируется и число приобретает вид, как если бы запись была без него.

В десятичных числах подчёркивание можно использовать в середине литерала, но не перед точкой и не после неё, например:

10_10,
10_10.10_10,
10.10E-10_0

В недесятичных числах подчёркивание допускается после литералов, обозначающих систему счисления:

0x_FFFF,
0xFF_FF,
0x_FF_FF

Предупреждение

Подчёркивание в начале и в конце литерала, двойное подчёркивание не допускается ни в каких случаях. Следующие варианты записи приведут к ошибке:

0xFF__FF,
0xFFFF_,
_1010,
1010._1010,
10.10E_-100_

Примеры использования подчёркиваний в числовых литералах:

SELECT 1234567_890 FROM rdb$database;      -- 1234567890
SELECT -1_234_567_890 FROM rdb$database;   -- -1234567890
SELECT 123_45.67809 FROM rdb$database;     -- 12345.67809
SELECT 123000E-1_0 FROM rdb$database;      -- 1.230000000000000e-05
SELECT 0o12_34_56_70 FROM rdb$database;    -- 2739128
SELECT -0o_12345670 FROM rdb$database;     -- -2739128

Константы даты и времени

Константы даты и времени имеют некоторую специфику. Для представления даты используется множество форматов:

dd.mm.yyyy
mm-dd-yyyy
mm/dd/yyyy
yyyy-mm-dd
yyyy/mm/dd
yyyy.mm.dd
dd-MON-yyyy

Здесь MON — трехсимвольное сокращенное название месяца (английское). Может принимать значения в любом регистре: jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec (месяцы с января по декабрь). При описании формата типа данных для указания номера дня в месяце используются символы «dd» (число от 1 до 31), для месяца в году — «mm» (число от 1 до 12), для номера года — «yyyy» (число от 1 до 9999).

Тип данных время позволяет хранить время с точностью до десятитысячной доли секунды (до 100 микросекунд) и задается литералом в виде:

hh:mm:ss.nnnn

Здесь hh — часы: число от 0 до 23, mm — минуты: число от 0 до 59, ss — секунды: число от 0 до 59, nnnn — десятитысячные доли секунды, число от 0000 до 9999. Для часов, минут и секунд ведущий ноль можно не указывать.

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

hh.mm.ss.nnnn

Более подробно все эти типы данных и операции над ними рассматриваются в главе 4.

2.9. Операторы SQL

SQL операторы включают в себя операторы для сравнения, вычисления, оценки и конкатенации значений.

<оператор> ::= <оператор конкатенации>
             | <арифметический оператор>
             | <оператор сравнения>
             | <логический оператор>
<оператор конкатенации> ::= ||

<арифметический оператор> ::= * | / | + | -

<оператор сравнения> ::=
               = | <> | != | ~= | ^= | > | < | >= | <= | !> | ~> | ^> | !< | ~< | ^<

<логический оператор> ::= NOT | AND | OR

Все операторы разбиты на 4 типа. Каждый тип оператора имеет свой приоритет. Чем выше приоритет типа оператора, тем раньше он будет вычислен. Внутри одного типа операторы имеют собственный приоритет, который также определяет порядок их вычисления в выражении. Операторы с одинаковым приоритетом вычисляются слева направо. Для изменения порядка вычислений операции могут быть сгруппированы с помощью круглых скобок.

Таблица 2.3 Приоритеты операторов

Тип оператора

Приоритет

Пояснение

Конкатенация

1

Строки объединяются до выполнения любых других операций.

Арифметический

2

Арифметические операции выполняются после конкатенации строк, но перед выполнением операторов сравнения и логических операций.

Сравнение

3

Операции сравнения вычисляются после конкатенации строк и выполнения арифметических операций, но до логических операций.

Логический

4

Логические операторы выполняются после всех других типов операторов.

Таким образом порядок выполнения операций следующий:

  1. Действия в скобках.

  2. Операции конкатенации.

  3. Операции умножения и деления.

  4. Операции сложения и вычитания.

  5. Операции сравнения.

  6. Операторы IN, BETWEEN, LIKE, CONTAINING, STARTING WITH, IS NULL, IS DISTINCT FROM, функции EXISTS, SINGULAR, встроенные функции, UDF.

  7. Логическое отрицание.

  8. Конъюнкция.

  9. Дизъюнкция.

Оператор конкатенации

Оператор конкатенации || соединяет две символьные строки и создаёт одну строку. Символьные стоки могут быть константами или значениями, полученными из столбцов или других выражений.

SELECT LAST_NAME || ', ' || FIRST_NAME AS FULL_NAME FROM EMPLOYEE; 

Арифметические операторы

Таблица 2.4 Приоритет арифметических операторов

Оператор

Название

Приоритет

+

Унарный плюс

1

-

Унарный минус

1

*

Умножение

2

/

Деление

2

+

Сложение

3

-

Вычитание

3

UPDATE T SET A = 4 + 1/(B-C)*D

Оператор сравнения

Имеется шесть традиционных операторов сравнения:

Листинг 2.4 Операторы сравнения

<оператор сравнения> ::=   = , < , > , <= , >= , !< , !> , <> , != , ^= , ^> , ^<

В операторе сравнения символы «!» и «^» означают отрицание. Оператор может быть применен к любому типу данных столбцов таблицы, за исключением типа данных BLOB. Допустимо сравнение однотипных или близких типов данных. При необходимости можно выполнить явное преобразование типа у операндов сравнения, используя функцию CAST. Список операторов сравнения и их значение приведены в таблице 2.5:

Таблица 2.5 Приоритет операторов сравнения

Оператор

Название

Приоритет

=

Равно, идентично

2

<> , != , ^=, ~=

Не равно

2

>

Больше

2

<

Меньше

2

>=, !<, ^<, ~<

Больше или равно, не меньше

2

<=, !>, ^>, ~>

Меньше или равно, не больше

2

Результатом сравнения, когда один из операндов или оба имеют значение NULL, всегда будет UNKNOWN, то есть условие не выполняется.

Символьный тип данных можно сравнивать с любым типом данных, кроме BLOB. В таких операциях сравнения осуществляется неявное преобразование других типов данных к символьному. Лучшим же вариантом в сравнении является явное преобразование с использованием функции CAST сравниваемых типов данных к символьному типу.

Сравнение числовых данных между собой никогда не вызывает исключений. Например, можно сравнивать целочисленный тип данных с числом с фиксированной или с плавающей точкой.

Недопустимо сравнение даты или времени с числом или с символьным данным, содержащим строку, не являющуюся датой или временем (иногда это не приведет к выдаче синтаксической ошибки, но на практике не является разумным решением). Дату или время можно сравнивать с символьным данным, если строка содержит дату или время в «правильном» виде; при этом лучше всего следует выполнить явное преобразование строки к нужному типу, использовав функцию CAST.

Предупреждение

Нельзя дату сравнивать со временем.
SELECT *
FROM Pc
WHERE speed >= 500 AND price < 800;

SELECT *
FROM Printer
WHERE type = 'matrix' AND price < 300;

Оператор равенства

Оператор "=", который используется во многих условиях, сравнивает только значения со значениями. В соответствии со стандартом SQL, NULL не является значением и, следовательно, два значения NULL не равны и ни неравны друг с другом. Если необходимо, чтобы значения NULL соответствовали друг другу при объединении, используйте оператор IS NOT DISTINCT FROM. Этот оператор возвращает истину, если операнды имеют то же значение, или, если оба они равны NULL.

SELECT * FROM A
JOIN B ON A.id IS NOT DISTINCT FROM B.code;

Точно так же, если вы хотите чтобы значения NULL отличались от любого значения и два значения NULL считались равными, используйте оператор IS DISTINCT FROM вместо оператора "<>".

SELECT * FROM A
JOIN B ON A.id IS DISTINCT FROM B.code;

Логические операторы

В SQL используется не обычная двухзначная, а трехзначная логика. В ней присутствует не два, а три значения — TRUE (истина), FALSE (ложь) и UNKNOWN (неопределенное или неизвестное значение).

Таблица 2.6 Приоритет логических операторов

Оператор

Название

Приоритет

NOT

Отрицание условия поиска.

1

AND

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

2

OR

Объединяет два предиката и более, из которых должен быть истинным хотя бы один предикат, чтобы истинным был и весь предикат.

3

В операции отрицания присутствует один операнд. Результат выполнения отрицания представлен в таблице.

Таблица 2.7 Операция отрицания NOT

Операнд

NOT операнд

TRUE

FALSE

FALSE

TRUE

UNKNOWN

UNKNOWN

В операции дизъюнкции (логическое ИЛИ, OR) участвуют два операнда. Операция симметрична. Результат выполнения дизъюнкции показан в таблице.

Таблица 2.8 Операция дизъюнкции OR

Операнд 1

Операнд 2

Операнд 1 OR Операнд 2

TRUE

TRUE

TRUE

TRUE

FALSE

TRUE

FALSE

FALSE

FALSE

TRUE

UNKNOWN

TRUE

FALSE

UNKNOWN

UNKNOWN

UNKNOWN

UNKNOWN

UNKNOWN

В операции конъюнкции (логическое И, AND) участвуют два операнда. Операция симметрична. Результат выполнения конъюнкции показан в таблице.

Таблица 2.9 Операция дизъюнкции AND

Операнд 1

Операнд 2

Операнд 1 AND Операнд 2

TRUE

TRUE

TRUE

TRUE

FALSE

FALSE

FALSE

FALSE

FALSE

TRUE

UNKNOWN

UNKNOWN

FALSE

UNKNOWN

FALSE

UNKNOWN

UNKNOWN

UNKNOWN

2.10. Специальные символы

Существует набор специальных символов, используемых в качестве разделителей, знаков операций (арифметических, строковых, логических) и др.

<специальный символ SQL> ::= <пробел> | " | % | & | ' | ( | ) | * | + | , | - | . | / | : | ; | < | = | > | ? | [ | ] | ^{} | { | }

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

2.11. Комментарии

В SQL скриптах, операторах SQL и PSQL модулях могут встречаться комментарии. Комментарий — это произвольный текст заданный пользователем, предназначенный для пояснения работы отдельных частей программы. Синтаксический анализатор игнорирует текст комментариев. В РЕД Базе Данных поддерживается два типа комментариев: блочные и однострочные.

Листинг 2.5 Синтаксис комментария

<комментарий> ::= <блочный комментарий> | <однострочный комментарий>

<блочный комментарий> ::= /*<ASCII символ>[ <ASCII символ> …]*/

<однострочный комментарий>  ::= --<ASCII символ>[ <ASCII символ> …] <конец строки>

Блочные комментарии начинаются с символов /* и заканчиваются символами */. Блочные комментарии могут содержать текст произвольной длины и занимать несколько строк.

Однострочные комментарии начинаются с символов -- и действуют до конца текущей строки.

set term !;
CREATE PROCEDURE P(A INT)
RETURNS (B INT)
AS
BEGIN
  /* Данный текст не будет учитываться
  при работе процедуры, т.к. является комментарием
  */
  B = A + 1; -- Однострочный комментарий
  SUSPEND;
END!
set term ;!