Руководство по языку SQL СУБД Firebird 2.5 | Firebird |
![]() |
![]() |
Редакция 20 января 2020 — v.0500-1
Авторские права © 2019 Firebird Project и все авторы, в соответствии с лицензией Public Documentation License Version 1.0. Смотри Лицензионное соглашение в Приложении.
Содержание
Список таблиц
Список примеров
Это руководство описывает язык SQL, поддерживаемый СУБД Firebird 2.5.
Известно, что СУБД Firebird начала создаваться на основе открытого кода СУБД InterBase 6.0. В период с 2000 по 2014 год было выпущено 5 основных релизов Firebird: 1.0.х.х; 1.5.х; 2.0.х; 2.1.х; 2.5.х., релиз 3.0 запланирован на 2016 год.
Однако, за всё время развития проекта Firebird, а это более 10 лет, на русском языке до сих пор не было создано единой документации. Несколько переведённых материалов по отдельным вопросам можно было найти на официальном сайте http://www.firebirdsql.org/en/reference-manuals/. Но их, во-первых, очень мало, а во-вторых зачастую они уже неактуальны. Наибольшее количество русскоязычной информации о Firebird находится на сайте http://ibase.ru/develop.htm, за что огромное спасибо Дмитрию Кузьменко (IBSurgeon/iBase.ru).
Но единой русскоязычной документации о Firebird до сих пор не существовало.
Данное «Руководство по языку SQL СУБД Firebird» — это первый русскоязычный документ, полностью освещающий все аспекты и особенности работы с языком SQL Firebird для текущей (актуальной) на сегодняшний день версии СУБД Firebird 2.5. В руководстве также приводятся практические примеры использования SQL, многие из которых взяты из реальной практики.
Данный документ содержит описание языка SQL Firebird. Он охватывает следующие основные области:
Основные положения;
Зарезервированные и ключевые слова;
Типы и подтипы данных;
Операторы DDL (Data Definition Language — язык создания данных);
Операторы DML (Data Manipulation Language — язык обращения с данными);
Операторы управления транзакциями;
Обработка исключений;
Операторы PSQL (Procedural SQL — процедурный SQL, используется в хранимых процедурах, триггерах и выполнимых блоках);
Безопасность и операторы управления доступом;
Операторы и предикаты (утверждения);
Агрегатные функции;
Встроенные функции;
Коды ошибок и обработка исключительных ситуаций;
Описание системных таблиц и таблиц мониторинга;
Наборы символов и соответствующие им порядки сортировки.
Вопросы, не связанные с SQL в данном документе не рассматриваются.
В работе над руководством принимали участие:
Симонов Денис;
Винкенуг Пол;
Дмитрий Филиппов;
Дмитрий Еманов;
Александр Карпейкин;
Алексей Ковязин;
Дмитрий Кузьменко.
Редакторы – Александр Карпейкин, Дмитрий Кузьменко, Алексей Ковязин, Денис Симонов.
Платиновым спонсором создания «Руководства по языку СУБД Firebird» является Московская Биржа www.moex.com.
Московская Биржа — крупнейший в России и Восточной Европе биржевой холдинг, образованный 19 декабря 2011 года в результате слияния биржевых групп ММВБ (основана в 1992) и РТС (основана в 1995). Московская Биржа входит в двадцатку ведущих мировых площадок по объему торгов ценными бумагами, суммарной капитализации торгуемых акций и в десятку крупнейших бирж производных финансовых инструментов.
Золотым спонсором «Руководства по языку СУБД Firebird» является IBSurgeon (iBase.ru) (www.ib-aid.com, www.ibase.ru): техническая поддержка и инструменты разработчика и администратора для СУБД Firebird.
Благодарим Влада Хорсуна, Александра Пешкова, Павла Зотова за помощь в создании этого документа.
Содержание данного Документа распространяется на условиях лицензии «Public Documentation License Version 1.0» (далее «Лицензия»); Вы можете использовать этот Документ, только если согласны с условиями Лицензии. Копии текста Лицензии доступны по адресам http://www.firebirdsql.org/pdfmanual/pdl.pdf (PDF) и http://www.firebirdsql.org/manual/pdl.html (HTML).
Оригинальное название документа «Руководство по языку SQL Firebird».
Copyright (C) 2015. Все права защищены. Адрес электронной почты для контакта:
<case@firebirdsql.org>
Далее представлен оригинальный текст раздела, так как его перевод не имеет равноценной юридической силы.
The contents of this Documentation are subject to the Public Documentation License Version 1.0 (the "License"); you may only use this Documentation if you comply with the terms of this License. Copies of the License are available at http://www.firebirdsql.org/pdfmanual/pdl.pdf (PDF) and http://www.firebirdsql.org/manual/pdl.html (HTML).
Так как СУБД Firebird постоянно развивается, то изменяется и улучшается его документация. Вы можете получить самые свежие версии этого документа по адресам:
PDF — https://github.com/sim1984/langref25/releases/download/langref25/langref25.pdf
одностраничный HTML — https://github.com/sim1984/langref25/releases/download/langref25/langref25-html.zip
многостраничный HTML — https://github.com/sim1984/langref25/releases/download/langref25/langref25-html-chunks.zip
Исходный код проекта находится по адресу https://github.com/sim1984/langref25.
На официальном сайте firebirdsql.org документ доступен по адресу https://www.firebirdsql.org/file/documentation/reference_manuals/Firebird_Language_Reference_RUS.pdf
Кроме того, данный документ выложен в различных форматах на сайте ibase.ru http://www.ibase.ru/develop/
SQL имеет четыре подмножества SQL, используемых в различных областях применения:
Динамический SQL (DSQL, Dynamic SQL)
Процедурный SQL (PSQL, Procedural SQL)
Встроенный SQL (ESQL, Embedded SQL)
Интерактивный SQL (ISQL, Interactive SQL)
Динамический SQL является основной частью языка, которая соответствует Части 2 (SQL/Foundation – SQL/Основы) спецификации SQL. DSQL представляет собой конструкции, которые передаются клиентскими приложениями с помощью Firebird API и обрабатываются сервером базы данных.
Процедурный SQL является расширением Динамического SQL, в котором дополнительно присутствуют составные операторы, содержащие локальные переменные, присваивание, циклы и другие процедурные конструкции. PSQL относится к Части 4 (SQL/PSM) спецификации SQL. Изначально расширение PSQL было доступно только лишь в постоянно хранимых в базе модулях (процедурах и триггерах), но сравнительно недавно они стали также доступны в Динамическом SQL (смотри EXECUTE BLOCK).
Встроенный SQL определяет подмножество DSQL, поддерживаемое средством Firebird GPRE. GPRE — приложение-препроцессор, которое позволяет вам внедрять SQL конструкции в ваш непосредственный язык программирования (C, C++, Pascal, Cobol и так далее) и производить обработку этих внедрённых конструкций в правильные вызовы Firebird API. Обратите внимание, что ESQL поддерживает только часть конструкций и выражений DSQL.
Интерактивный SQL подразумевает собой язык, который может быть использован для работы с приложением командной строки Firebird ISQL для интерактивного доступа к базам данных. isql является обычным клиентским приложением. Для него обычный язык — это язык DSQL. Однако приложение поддерживает несколько дополнительных команд.
Оба языковых подмножества, как DSQL, так и PSQL полностью представлены в данном руководстве. Из набора инструментария ни ESQL, ни ISQL не описаны здесь отдельно, за исключением тех мест, где это указано явно.
SQL диалект — это термин, определяющий специфические особенности языка SQL, которые доступны во время доступа с его помощью к базе данных. SQL диалект может быть определён как на уровне базы данных, так и на уровне соединения с базой данных. В настоящее время доступны три диалекта:
В 1-м диалекте дата и время хранятся в типе данных DATE, и имеется тип данных TIMESTAMP, который идентичен DATE. Двойные кавычки используются для разграничения строковых данных. Точность типов данных NUMERIC и DECIMAL меньше, чем в 3-м диалекте и в случае, если значение точности более 9, Firebird хранит такие значения как длинные значения с плавающей точкой. BIGINT не является доступным типом данных. Идентификаторы являются регистро-независимыми. Значение генераторов хранится как 64 битное целое, а при выдаче значения усекается до 32 битного целого;
Диалект 2 доступен только в клиентском соединении к Firebird и не может быть применён к базе данных. Он предназначен для того, чтобы помочь в отладке в случае возможных проблем с целостностью данных при проведении миграции с диалекта 1 на 3;
Диалект 3 базы данных позволяет хранить числа (типы данных DECIMAL и NUMERIC) в базе данных как длинные значения с фиксированной точкой (масштабируемые целые числа) в случае если точность числа меньше чем 9. Тип данных TIME доступен и используется для хранения значения только времени. Тип данных DATE хранит информацию о дате. Тип данных BIGINT доступен в качестве целого 64-х битного типа данных. Двойные кавычки могут использоваться, но только для идентификаторов, которые являются зависимыми от регистра, а не для строковых данных, для которых используют одинарные кавычки. Значения генераторов хранятся как 64-ти битные целые значения. Новую базу данных Firebird создаёт в 3-м диалекте.
Целью 1-го диалекта является обеспечение поддержки для унаследованных (пре-версия IB6) Interbase приложений для работы с Firebird. Диалект 2 используется как промежуточный и предназначен для разрешения проблем при миграции с 1-го в 3-й диалект. Для вновь разрабатываемых баз данных и приложений настоятельно рекомендуется использовать 3-й диалект. Диалект при соединении с базой данных должен быть таким же, как и базы данных. Исключением является случай миграции с 1-го в 3-й диалект, когда в строке соединения с базой данных используется 2-й диалект.
По умолчанию это руководство описывает семантику SQL третьего диалекта, если только в тексте явно не указывается диалект.
Основная конструкция SQL — оператор (statement). Оператор описывает, что должна выполнить система управления базами данных с конкретным объектом данных или метаданных, обычно не указывая, как именно это должно быть выполнено. Достаточно сложные операторы содержат более простые конструкции — предложения (clause) и варианты, альтернативы (options). Предложение описывает некую законченную конструкцию в операторе. Например, предложение WHERE в операторе SELECT и в ряде других операторов (UPDATE, DELETE) задаёт условия поиска данных в таблице (таблицах), подлежащих выборке, изменению, удалению. Предложение ORDER BY задаёт характеристики упорядочения выходного, результирующего, набора данных. Альтернативы, будучи наиболее простыми конструкциями, задаются при помощи конкретных ключевых слов и определяют некоторые дополнительные характеристики элементов предложения (допустимость дублирования данных, варианты использования и др.).
В SQL существуют ключевые слова и зарезервированные слова. Ключевые слова — это все слова, входящие в лексику (словарь) языка SQL. Ключевые слова можно (но не рекомендуется) использовать в качестве имён, идентификаторов объектов базы данных, внутренних переменных и параметров. Зарезервированные слова — это те ключевые слова, которые нельзя использовать в качестве имён объектов базы данных, переменных или параметров.
Например, следующий оператор будет выполнен без ошибок потому, что ABS является ключевым, но не зарезервированным словом.
CREATE TABLE T (ABS INT NOT NULL);
При выполнении такого оператора будет выдана ошибка потому, что ADD является ключевым и зарезервированным словом.
CREATE TABLE T (ADD INT NOT NULL);
Список зарезервированных и ключевых слов представлен в приложении Зарезервированные и ключевые слова.
Все объекты базы данных имеют имена, которые иногда называют идентификаторами. Максимальная длина идентификатора составляет 31 байт. Существует два типа имён — имена, похожие по форме на имена переменных в обычных языках программирования, и имена с разделителями (delimited name), которые являются отличительной особенностью языка SQL.
Обычное имя должно начинаться с буквы латинского алфавита, за которой могут следовать буквы (латинского алфавита), цифры, символ подчёркивания и знак доллара. Такое имя нечувствительно к регистру, его можно записывать как строчными, так и прописными буквами. В имени нельзя использовать буквы кириллицы, пробелы, другие специальные символы.
Следующие имена с точки зрения системы являются одинаковыми:
fullname FULLNAME FuLlNaMe FullName
Синтаксис:
<name>
::=<letter>
|<name>
<letter>
|<name>
<digit>
|<name>
_ |<name>
$<letter>
::=<upper letter>
|<lower letter>
<upper letter>
::= 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<lower letter>
::= 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<digit>
::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
Имя с разделителями заключается в двойные кавычки. Оно может содержать любые символы, включая буквы кириллицы, пробелы, специальные символы. В нем также могут присутствовать зарезервированные слова. Такое имя является чувствительным к регистру. Имена с разделителем доступны только в диалекте 3. Подробнее о диалектах см. Диалекты SQL
<delimited name>
::= "<ASCII char>
[<ASCII char>
…]"
Следует иметь в виду, что конечные пробелы в именах с разделителями, как и в любых строковых константах, отбрасываются.
Существует определённая похожесть и отличие обычных имён и имён с разделителями. Такие имена с разделителями и обычные, как "FULLNAME" и FULLNAME являются одинаковыми, а "FullName" и FULLNAME (так же как, например, и FullName) отличаются.
Литералы служат для непосредственного представления данных, ниже приведён список стандартных литералов:
целочисленные — 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.
Подробней о литералах для каждого из типов данных см. Типы и подтипы данных.
Существует набор специальных символов, используемых в качестве разделителей.
<special char>
::=<space>
| " | % | & | ' | ( | ) | * | + | , | - | . | / | : | ; | < | = | > | ? | [ | ] | ^ | { | } | |
Часть этих символов, а так же их комбинации могут быть использованы как операторы (арифметические, строковые, логические), как разделители команд SQL, для квотирования идентификаторов, и для обозначения границ строковых литералов или комментариев.
Синтаксис:
<operator>
::=<string operator>
|<arithmetic operator>
|<comparison operator>
|<logical operator>
<string operator>
::= {||}<arithmetic operator>
::= * | / | + | - |<comparison operator>
::= {=} | {<>} | {!=} | {~=} | {^=} | {>} | {<} | {>=} | {<=} | {!>} | {~>} | {^>} | {!<} | {~<} | {^<}<logical operator>
::= NOT | AND | OR
Подробнее об операторах см. Выражения.
В SQL скриптах, операторах SQL и PSQL модулях могут встречаться комментарии. Комментарий — это произвольный текст заданный пользователем, предназначенный для пояснения работы отдельных частей программы. Синтаксический анализатор игнорирует текст комментариев. В Firebird поддерживается два типа комментариев: блочные и однострочные.
Синтаксис:
<comment>
::=<block comment>
|<single-line comment>
<block comment>
::= /*<ASCII char>
[<ASCII char>
…]*/<single-line comment>
::= --<ASCII char>
[<ASCII char>
…]<end line>
Блочные комментарии начинается с символов /* и заканчивается символами */. Блочные комментарии могут содержать текст произвольной длины и занимать несколько строк.
Однако, если в блоке комментария присутствует последовательность символов '*/', то блочный комментарий будет немедленно завершён при обнаружении символов */.
Однострочные комментарии начинаются с символов -- и действуют до конца текущей строки.
Пример 1.1. Комментарии
CREATE PROCEDURE P(APARAM INT) RETURNS (B INT) AS BEGIN /* Данный текст не будет учитываться при работе процедуры, т.к. является комментарием */ B = A + 1; -- Однострочный комментарий SUSPEND; END
Типы данных используются в случае:
определения столбца в таблице базы данных в операторе CREATE TABLE или для его изменения с использованием ALTER TABLE;
при объявлении и редактировании домена оператором CREATE DOMAIN/ALTER DOMAIN;
при объявлении локальных переменных в хранимых процедурах, PSQL-блоках и триггерах, при указании аргументов хранимых процедур;
при описании внешних функций (UDF – функций, определённых пользователем) для указания аргументов и возвращаемых значений;
при явном преобразовании типов данных в качестве аргумента для функции CAST.
Таблица 2.1. Типы данных Firebird
Название | Размер | Диапазон и точность | Описание |
---|---|---|---|
BIGINT | 64 бита | -263 .. 263 - 1 | Тип данных доступен только в 3 диалекте. |
BLOB | Переменный | Нет. Размер сегмента BLOB ограничивается 64К. Максимальный размер поля BLOB 4 Гб. Для размера страницы 4096 максимальный размер BLOB поля несколько ниже 2 Гб. | Тип данных с динамически изменяемым размером для хранения больших данных, таких как графика, тексты, оцифрованные звуки. Базовая структурная единица — сегмент. Подтип Blob описывает содержимое. |
CHAR( CHARACTER( |
n символов (размер в байтах зависит от
кодировки, кол-во байт на символ)
|
от 1 до 32 767 байт | Символьный тип данных фиксированной длины. При извлечении данных,
строка дополняется пробелами справа до указанной длины. Если количество
символов n не указано, то по умолчанию
принимается 1.
|
DATE | 32 бита | От 01.01.0001 н.э. до 31.12.9999 н.э. | ISC_DATE |
DECIMAL (precision ,
scale )
|
Переменный (16, 32 или 64 бита) |
|
scale должно быть меньше или равно
precision . Число с десятичной точкой,
имеющей после точки scale разрядов. Пример:
DECIMAL(10,3) содержит число точно в следующем формате: ppppppp.sss.
|
DOUBLE PRECISION | 64 бита | 2,225 x 10-308 .. 1,797 x 10308 | IEEE двойной точности, 15 цифр, размер зависит от платформы |
FLOAT | 32 бита | 1,175 x 10-38 .. 3,402 x 1038 | IEEE одинарной точности, 7 цифр |
INTEGER INT |
32 бита | –2 147 483 648 .. 2 147 483 647 | signed long |
NUMERIC (precision ,
scale )
|
Переменный (16, 32 или 64 бита) |
|
scale должно быть меньше или равно
precision. Число с десятичной точкой, имеющей после точки scale
разрядов. Пример: NUMERIC(10,3) содержит число точно в следующем
формате: ppppppp.sss.
|
SMALLINT | 16 бит | –32 768 .. 32 767 | signed short (word) |
TIME | 32 бита | От 0:00 до 23:59:59.9999 | ISC_TIME |
TIMESTAMP | 64 бита | От 01.01.0001 н.э. до 31.12.9999 н.э. | Включает информацию и о времени |
VARCHAR( CHAR VARYING CHARACTER VARYING |
n символов (размер в байтах зависит от
кодировки, кол-ва байт на символ)
|
От 1 до 32 765 байтов | Размер символов в байтах с учётом их кодировки не может быть больше 32765. Для этого типа данных, в отличие от CHAR (где по умолчанию предполагается количество символов 1), количество символов n обязательно должно быть указано. |
Следует иметь в виду, что временной ряд из дат прошлых веков рассматривается без учёта реальных исторических фактов и так, как будто бы во всем этом диапазоне ВСЕГДА действовал только Григорианский календарь.
Для целых чисел используют целочисленные типы данных SMALLINT, INTEGER и BIGINT (в 3 диалекте). Firebird не поддерживает беззнаковый целочисленный тип данных.
Тип данных SMALLINT представляет собой 16-битное целое. Он применяется в случае, когда не требуется широкий диапазон возможных значений для хранения данных.
Числа типа SMALLINT находятся в диапазоне -215 .. 215 - 1, или -32 768 .. 32 767.
Примеры:
CREATE DOMAIN DFLAG AS SMALLINT DEFAULT 0 NOT NULL CHECK (VALUE=-1 OR VALUE=0 OR VALUE=1); CREATE DOMAIN RGB_VALUE AS SMALLINT;
Тип данных INTEGER представляет собой 32-битное целое. Сокращённый вариант записи типа данных INT.
Числа типа INTEGER находятся в диапазоне -231 .. 231 - 1, или -2 147 483 648 .. 2 147 483 647.
Примеры:
CREATE TABLE CUSTOMER ( CUST_NO INTEGER NOT NULL, CUSTOMER VARCHAR(25) NOT NULL, CONTACT_FIRST VARCHAR(15), CONTACT_LAST VARCHAR(20), ... PRIMARY KEY (CUST_NO) );
BIGINT — это SQL-99-совместимый 64 битный целочисленный тип данных. Он доступен только в 3-м диалекте. При использовании клиентом диалекта 1, передаваемое сервером значение генератора усекается до 32-х битного целого (INTEGER). При подключении в 3-м диалекте значение генератора имеет тип BIGINT.
Числа типа BIGINT находятся в диапазоне -263 .. 263 - 1, или -9 223 372 036 854 775 808 .. 9 223 372 036 854 775 807.
Числа типа BIGINT могут быть заданы в шестнадцатеричном виде с 9 — 16 шестнадцатеричными цифрами. Более короткие шестнадцатеричные числа интерпретируются как тип данных INTEGER.
Примеры:
Пример 2.1. Использование типа BIGINT
CREATE TABLE WHOLELOTTARECORDS (
ID BIGINT NOT NULL PRIMARY KEY,
DESCRIPTION VARCHAR(32)
);
Начиная с Firebird 2.5, константы трех целочисленных типов можно указать в шестнадцатеричном формате с помощью 9-16 шестнадцатеричных цифр для BIGINT или 1 до 8 цифр для INTEGER. Запись SMALLINT в шестнадцатеричном представлении не поддерживается в явном виде, но Firebird будет прозрачно преобразовывать шестнадцатеричное число в SMALLINT, если это необходимо, при условии что оно попадает в допустимый диапазон положительных и отрицательных значений для SMALLINT.
Использование и диапазоны значений чисел шестнадцатеричной нотации более подробно описаны в ходе обсуждения целочисленных констант в главе под названием Общие элементы языка.
Примеры:
Пример 2.2. Использование целых чисел заданных шестнадцатеричном виде
INSERT INTO MYBIGINTS VALUES ( -236453287458723, 328832607832, 22, -56786237632476, 0X6F55A09D42, -- 478177959234 0X7FFFFFFFFFFFFFFF, -- 9223372036854775807 0XFFFFFFFFFFFFFFFF, -- -1 0X80000000, -- -2147483648, т.е. INTEGER 0X080000000, -- 2147483648, т.е. BIGINT 0XFFFFFFFF, -- -1, т.е. INTEGER 0X0FFFFFFFF -- 4294967295, т.е. BIGINT );
Шестнадцатеричный INTEGER автоматически приводится к типу BIGINT перед вставкой в таблицу. Однако это происходит после установки численного значения, так 0x80000000 (8 цифр) и 0x080000000 (9 цифр) будут сохранены в разных форматах. Значение 0x80000000 (8 цифр) будет сохранено в формате INTEGER, а 0x080000000 (9 цифр) как BIGINT.
Типы данных с плавающей точкой хранятся в двоичном формате IEEE 745, который включает в себя знак, показатель степени и мантиссу. Точность этого типа является динамической, что соответствует физическому формату хранения, который составляет 4 байта для типа FLOAT и 8 байт для типа DOUBLE PRECISION.
Учитывая особенности хранения чисел с плавающей точкой, этот тип данных не рекомендуется использовать для хранения денежных данных. По тем же причинам не рекомендуется использовать столбцы с данными такого типа в качестве ключей и применять к ним ограничения уникальности.
При проверке данных столбцов с типами данных с плавающей точкой рекомендуется вместо точного равенства использовать выражения проверки вхождения в диапазон, например, BETWEEN.
При использовании таких типов данных в выражениях рекомендуется крайне внимательно и серьёзно подойти к вопросу округления результатов расчётов.
Данные типы данных позволяют применять их для хранения денежных значений и обеспечивают предсказуемость операций умножения и деления.
Firebird предлагает два типа данных с фиксированной точкой: NUMERIC и DECIMAL. В соответствии со стандартом оба типа ограничивают хранимое число объявленным масштабом (количеством чисел после запятой). При этом подход к тому, как ограничивается точность для типов разный: для столбцов NUMERIC точность является такой, «как объявлено», в то время как DECIMAL столбцы могут получать числа, чья точность, по меньшей мере, равна тому, что было объявлено.
Например, NUMERIC(4, 2) описывает число, состоящее в общей сложности из четырёх цифр, включая 2 цифры после запятой; итого 2 цифры до запятой, 2 после. При записи в столбец с этим типом данных значений 3,1415 в столбце NUMERIC(4, 2) будет сохранено значение 3,14.
Для данных с фиксированной точкой общим является форма декларации, например,
NUMERIC(p
, s
). Здесь важно
понять, что в этой записи s
— это масштаб, а не интуитивно
предсказываемое «количество знаков после запятой». Для
«визуализации» механизма хранения данных запомните для себя процедуру:
При сохранении в базу данных число умножается на
10s (10 в степени
s
), превращаясь в целое;
При чтении данных происходит обратное преобразование числа.
Способ физического хранения данных в СУБД зависит от нескольких факторов: декларируемой точности, диалекта базы данных, типа объявления.
Таблица 2.2. Способ физического хранения чисел с фиксированной точкой
Точность | Тип данных | Диалект 1 | Диалект 3 |
---|---|---|---|
1 - 4 | NUMERIC | SMALLINT | SMALLINT |
1 - 4 | DECIMAL | INTEGER | INTEGER |
5 - 9 | NUMERIC и DECIMAL | INTEGER | INTEGER |
10 - 18 | NUMERIC и DECIMAL | DOUBLE PRECISION | BIGINT |
Формат объявления данных:
NUMERIC(p
,s
)
В зависимости от точности p
и масштаба
s
СУБД хранит данные по-разному.
Приведём примеры того, как СУБД хранит данные в зависимости от формы их объявления:
NUMERIC(4) SMALLINT NUMERIC(4,2) SMALLINT (data * 102) NUMERIC(10,4) DOUBLE PRECISION в 1-ом диалекте BIGINT в 3-ем диалекте (data * 104)
Всегда надо помнить, что формат хранения данных зависит от точности. Например, вы задали тип столбца NUMERIC(2, 2), предполагая, что диапазон значений в нем будет -0.99...0.99. Однако в действительности диапазон значений в столбце будет -327.68..327.67, что объясняется хранением типа данных NUMERIC(2, 2) в формате SMALLINT. Фактически типы данных NUMERIC(4, 2), NUMERIC(3, 2) и NUMERIC(2, 2) являются одинаковыми. Т.е. Для реального хранения данных в столбце с типом данных NUMERIC(2, 2) в диапазоне -0.99...0.99 для него надо создавать ограничение.
Формат объявления данных:
DECIMAL(p
,s
)
Формат хранения данных в базе во многом аналогичен NUMERIC, хотя существуют некоторые особенности, которые проще всего пояснить на примере.
Приведём примеры того, как СУБД хранит данные в зависимости от формы их объявления:
DECIMAL(4) INTEGER DECIMAL(4,2) INTEGER (data * 102) DECIMAL(10,4) DOUBLE PRECISION в 1-ом диалекте BIGINT в 3-ем диалекте (data * 104)
Функции MIN, MAX, SUM, AVG работают со всеми точными числовыми типами. SUM и AVG являются точными, если обрабатываемая запись имеет точный числовой тип, а масштабированная сумма соответствует 64 битам: в противном случае возникает исключение переполнения. SUM и AVG никогда не вычисляются с использованием арифметики с плавающей запятой, если тип данных столбца не является приблизительным числом.
Функции MIN и MAX для точного числового столбца возвращают точный числовой результат, имеющий ту же точность и масштаб, что и столбец. SUM и AVG для точного числового типа возвращает результат типа NUMERIC (18, S) или DECIMAL (18, S), где S - масштаб столбца. (Стандарт SQL определяет масштаб результата в таких случаях, в то время как точность SUM или AVG для столюцов с фиксированной точкой определяется реализацией: мы определяем его как 18.)
Если два операнда OP1 и OP2 являются точными числами с масштабами S1 и S2
соответственно, то OP1 + OP2
и OP1 - OP2
являются точными
числами с точностью 18 и масштабом равному наибольшему из значений S1 и S2, тогда
как для OP1 * OP2
и OP1 / OP2
являются точными числами с
точностью 18 и шкалой S1 + S2
. (Масштабы этих операций, кроме
разделения, определяются стандартом SQL. Точность всех этих операций и масштаб при
делении стандартом не регламентируются, а определяются реализацией: Firebird
определяет точность как 18, а масштаб деления как S1 + S2
, такой же,
что определён стандартом в для умножения.)
Всякий раз, когда выполняется арифметические операции с точными числовыми типами, в случае потери точности будет сообщено об ошибке переполнения, а не возвращёно неправильное значение. В качестве примера, который может быть неочевидным для читателя, если столбец DECIMAL (18,4) содержит наиболее отрицательное значение этого типа, -922337203685477.5808, попытка разделить этот столбец на -1 будет сообщать об ошибке переполнения, поскольку истинный результат превышает наибольшее положительное значение, которое может быть представлено в типе, а именно 922337203685477.5807.
Если один операнд является точным числом, а другой приблизительным числом, то результатом любого из четырех диадических операторов будет типа DOUBLE PRECISION. (В стандарте говорится, что результат является приблизительным числом с точностью, по крайней мере, такой же, как точность приблизительного числового операнда: Firebird удовлетворяет этому требованию, всегда используя DOUBLE PRECISION, который является максимальным приблизительным числовым типом, который предоставлен в Firebird.)
В СУБД Firebird для работы с данными, содержащими дату и время, используются типы данных DATE, TIME, TIMESTAMP. В 3-м диалекте присутствуют все три вышеназванных типа данных, а в 1-м для операций с датой и временем доступен только тип данных DATE, который не тождественен типу данных DATE 3-го диалекта, а напоминает тип данных TIMESTAMP из 3-го диалекта.
В диалекте 1 тип DATE может быть объявлен как TIMESTAMP. Такое объявление является рекомендуемым для новых баз данных в 1-м диалекте.
В типах DATETIME и TIME Firebird хранит секунды с точностью до десятитысячных долей. Если вам необходима более низкая гранулярность, то точность может быть указана явно в виде тысячных, сотых или десятых долей секунды в базах данных в 3 диалекте и ODS 11 и выше.
Временная часть типов TIME или TIMESTAMP представляет собой 4-байтный целое (WORD) вмещающее значение времени с долями секунды, и хранящаяся как количество десятитысячных долей секунды прошедших с полуночи. Фактическая точность значений полученных из time(stamp) функций и переменных будет следующей:
CURRENT_TIME — по умолчанию имеет точность до секунды, точность до миллисекунд может быть указана следующим образом
CURRENT_TIME (0 | 1 | 2 | 3)
CURRENT_TIMESTAMP — по умолчанию имеет точность до миллисекунды, точность от секунд до миллисекунд может быть указана следующим образом
CURRENT_TIMESTAMP (0 | 1 | 2 | 3)
Литерал 'NOW' имеет точность до миллисекунд;
Функции DATEADD и DATEDIFF поддерживает точность до миллисекунд. Десятые доли миллисекунды могут указаны, но они будут округлены до ближайшего целого числа перед выполнением любой операции;
Функция EXTRACT возвращает значения с точностью до десятых долей миллисекунды для аргументов SECOND и MILLISECOND;
В 3-м диалекте тип данных DATE, как это и следует предположить из названия, хранит только одну дату без времени. В 1-м диалекте тип DATE эквивалентен типу TIMESTAMP и хранит дату вместе со временем.
Допустимый диапазон хранения от 1 января 1 г. н.э. до 31 декабря 9999 года.
В случае необходимости сохранять в 1 диалекте только значения даты, без времени, при записи в таблицу добавляйте время к значению даты в виде литерала '00:00:00.0000'.
Этот тип данных доступен только в 3-м диалекте. Позволяет хранить время дня в диапазоне от 00:00:00.0000 до 23:59:59.9999.
При необходимости получения времени из типа DATE в 1-м диалекте можно использовать функцию EXTRACT.
Пример 2.3. Пример использования EXTRACT
EXTRACT (HOUR FROM DATE_FIELD) EXTRACT (MINUTE FROM DATE_FIELD) EXTRACT (SECOND FROM DATE_FIELD)
См. также описание функции EXTRACT в главе под названием Встроенные функции и переменные.
Для записи литералов даты и времени в Firebird используются сокращенные "C-style" выражения. Строковое представление даты и времени должно быть в одном из разрешённых форматов.
Синтаксис:
<date_literal>
::= DATE {<date>
| {'NOW' | 'TODAY' | 'TOMORROW' | 'YESTERDAY'} }<time_literal>
::= TIME {<time>
| 'NOW'}<timestamp_literal>
::= TIMESTAMP {<timestamp>
| {'NOW' | 'TODAY' | 'TOMORROW' | 'YESTERDAY'} }<date>
::= [YYYY
<p>
]MM
<p>
DD
|MM
<p>
DD
[<p>
YYYY
] |DD
<p>
MM
[<p>
YYYY
] |MM
<p>
DD
[<p>
YY
] |DD
<p>
MM
[<p>
YY
]<time>
:=HH
[:mm
[:SS
[.NNNN
]]]<timestamp>
::=<date>
<time>
<p>
::=whitespace
| . | : | , | - | /
Таблица 2.3. Описание формата даты и времени
Аргумент | Описание |
---|---|
datetime |
Строковое представление даты-времени. |
date |
Строковое представление даты. |
time |
Строковое представление времени. |
YYYY |
Год из четырёх цифр. |
YY |
Последние две цифры года (00-99). |
MM |
Месяц. Может содержать 1 или 2 цифры (1-12 или 01-12). В качестве месяца допустимо также указывать трёхбуквенное сокращение или полное наименование месяца на английском языке, регистр не имеет значение. |
DD |
День. Может содержать 1 или 2 цифры (1-31 или 01-31). |
HH |
Час. Может содержать 1 или 2 цифры (0-23 или 00-23). |
mm |
Минуты. Может содержать 1 или 2 цифры (0-59 или 00-59). |
SS |
Секунды. Может содержать 1 или 2 цифры (0-59 или 00-59). |
NNNN |
Десятитысячные доли секунды. Может содержать от 1 до 4 цифр (0-9999). |
p |
Разделитель, любой из разрешённых символов, лидирующие и завершающие пробелы игнорируются. |
Правила:
В формате Год-Месяц-День, год обязательно должен содержать 4 цифры;
Для дат в формате с завершающим годом, если в качестве разделителя дат используется точка «.», то дата интерпретируется в форме День-Месяц-Год, для остальных разделителей она интерпретируется в форме Месяц-День-Год;
Если год не указан, то в качестве года берётся текущий год;
Если указаны только две цифры года, то для получения столетия Firebird использует алгоритм скользящего окна. Задача заключается в интерпретации двухсимвольного значения года как ближайшего к текущему году в интервале предшествующих и последующих 50 лет;
Если не указан один из элементов времени, то оно принимается равным 0.
Настоятельно рекомендуем в литералах дат использовать только формы с полным указанием года в виде 4 цифр во избежание путаницы.
Примеры:
SELECT date '04.12.2014' AS d1, -- DD.MM.YYYY date '12-04-2014' AS d2, -- MM-DD-YYYY date '12/04/2014' AS d3, -- MM/DD/YYYY date '04.12.14' AS d4, -- DD.MM.YY -- DD.MM в качестве года берётся текущий date '04.12' AS d5, -- MM/DD в качестве года берётся текущий date '12/4' AS d6, date '2014/12/04' AS d7, -- YYYY/MM/DD date '2014.12.04' AS d8, -- YYYY.MM.DD date '2014-12-04' AS d9, -- YYYY-MM-DD -- дата на момент подготовки запроса date 'NOW' AS d10, -- дата на момент подготовки запроса date 'TODAY' AS d11, -- дата на 1 день меньше даты подготовки запроса date 'YESTERDAY' AS d12, -- дата на 1 день больше даты подготовки запроса date 'TOMORROW' AS d13, time '11:37' AS t1, -- HH:mm time '11:37:12' AS t2, -- HH:mm:ss time '11:31:12.1234' AS t3, -- HH:mm:ss.nnnn -- время на момент подготовки запроса time 'NOW' AS t4, -- DD.MM.YYYY HH:mm timestamp '04.12.2014 11:37' AS dt1, -- MM/DD/YYYY HH:mm:ss timestamp '12/04/2014 11:37:12' AS dt2, -- DD.MM.YYYY HH:mm:ss.nnnn timestamp '04.12.2014 11:31:12.1234' AS dt3, -- дата и время на момент подготовки запроса timestamp 'NOW' AS dt4, -- дата на момент подготовки запроса, время 00:00:00 timestamp 'TODAY' AS dt5, -- дата на 1 день меньше даты подготовки запроса, время 00:00:00 timestamp 'YESTERDAY' AS dt6, -- дата на 1 день больше даты подготовки запроса, время 00:00:00 timestamp 'TOMORROW' AS dt7 FROM rdb$database
Обратите внимание, что эти сокращённые выражения вычисляются сразу же во время синтаксического анализа (подготовки запроса или компиляции процедуры, функции или триггера).
Не рекомендуем использовать сокращённые выражения для специальных строковых литералов 'NOW', 'TODAY', 'TOMORROW', 'YESTERDAY'. Использование таких выражений в компилируемом PSQL приводит к тому, что значение "замораживается" на момент компиляции, и в результате возвращаются не актуальные значения. В Firebird 4.0 сокращённые выражения для таких строковых литералов будут запрещены, однако вы по прежнему сможете использовать их при приведении типа оператором CAST.
См. также: Преобразование строк в дату и время.
Благодаря способу хранения даты и времени с этими типами возможны арифметические операции вычитания из более поздней даты (времени) более раннюю. Дата представлена количеством дней с "нулевой даты" – 17 ноября 1858 г. Время представлено количеством секунд (с учётом десятитысячных долей), прошедших с полуночи.
Таблица 2.4. Арифметические операции для типов данных даты и времени
Операнд 1 | Оператор | Операнд 2 | Результат |
---|---|---|---|
DATE | + | TIME | TIMESTAMP |
DATE | + |
n
|
DATE, увеличенная на n целых дней
(дробная часть игнорируется).
|
TIME | + | DATE | TIMESTAMP |
TIME | + |
n
|
TIME, увеличенное на n секунд
(дробная часть учитывается)
|
TIMESTAMP | + |
n
|
TIMESTAMP, где дни увеличены на целую часть числа
n , плюс дробная часть числа
n (если указана) как количество
секунд в дне (с точностью до десятитысячных долей секунды).
|
DATE | - | DATE | Количество дней в интервале DECIMAL (9, 0) |
DATE | - |
n
|
DATE, уменьшенная на n целых дней
(дробная часть игнорируется)
|
TIME | - | TIME | Количество секунд в интервале DECIMAL (9, 4) |
TIME | - |
n
|
TIME, уменьшенное на n секунд
(дробная часть учитывается)
|
TIMESTAMP | - | TIMESTAMP | Количество дней и части дня в интервале DECIMAL (18, 9) |
TIMESTAMP | - |
n
|
TIMESTAMP, где дни уменьшены на целую часть числа
n , плюс дробная часть числа
n (если указана) как количество
секунд в дне (с точностью до десятитысячных долей секунды).
|
Одно значение даты/времени может быть вычтено из другого если:
Оба значения имеют один и тот же тип даты/времени;
Первый операнд является более поздним, чем второй.
В диалекте 1 тип DATE рассматривается как TIMESTAMP.
В СУБД Firebird для работы с символьными данными есть тип данных фиксированной длины CHAR и строковый тип данных VARCHAR переменной длины. Максимальный размер текстовых данных, хранящийся в этих типах данных, составляет 32767 байт для типа CHAR и 32765 байт для типа VARCHAR. Максимальное количество символов, которое поместится в этот объём, зависит от используемого набора символов CHARACTER SET и/или заданного порядка сортировки, который для символьных данных задаётся предложением COLLATE.
В случае отсутствия явного указания набора символов при описании текстового объекта базы данных будет использоваться набор символов по умолчанию, заданный при создании базы данных. При отсутствии явного указания набора символов, а также отсутствия набора символов по умолчанию в базе данных, поле получает набор символов CHARACTER SET NONE.
Если база данных будет содержать строки только с русским алфавитом, то для неё рекомендуется к использованию кодировка WIN1251. При её использовании на один символ расходуется 1 байт, соответственно максимальный размер текстовых полей для данной кодировки будет 32767 символов. Для стандартных операций сортировки при работе с WIN1251 не требуется задавать порядок сортировки (COLLATE).
В настоящее время все современные средства разработки поддерживают Unicode. При возникновении необходимости использования восточноевропейских текстов в строковых полях базы данных или для более экзотических алфавитов, рекомендуется работать с набором символов UTF8. При этом следует иметь в виду, что на один символ в данном наборе приходится до 4 байт. Следовательно, максимальное количество символов в символьных полях составит 32765/4 = 8191. При этом следует обратить внимание, что фактически значение параметра «байт на символ» зависит от диапазона, к которому принадлежит символ: английские буквы занимают 1 байт, русские буквы кодировки WIN1251 — 2 байта, остальные символы — могут занимать до 4-х байт.
Набор символов UTF8 поддерживает последнюю версию стандарта Unicode, до 4 байт на символ, поэтому для интернациональных баз рекомендуется использовать именно эту реализацию поддержки Unicode в Firebird.
При работе со строками необходимо помнить и о параметре соединения клиентской программы к базе данных. В нём также задаётся набор символов. В случае различия набора символов, при выдаче результата для строковых столбцов происходит автоматическая перекодировка как при передаче данных с клиента на сервер, так и в обратном направлении с сервера на клиента. То есть, совершенно нормальной является ситуация, когда база создана в кодировке WIN1251, а в настройках клиента в параметрах соединения стоит KOI8R или UTF8.
Набор символов NONE относится к специальным наборам символов. Его можно охарактеризовать тем, что каждый байт является частью строки, но в системе хранится без указаний, к какому фактическому набору символов они относятся. Разбираться с такими данными должно клиентское приложение, на него возлагается ответственность в правильной трактовке символов из таких полей.
Также к специальным наборам символов относится OCTETS. В этом случае данные рассматриваются как байты, которые могут в принципе не интерпретироваться как символы. OCTETS позволяет хранить бинарные данные и/или результаты работы некоторых функций Firebird. Правильное отображение данных пользователю, хранящихся в полях с CHARACTER SET OCTETS, также становится заботой клиентской стороны. При работе с подобными данными следует также помнить, что СУБД не контролирует их содержимое и возможно возникновение исключения при работе кода, когда идёт попытка отображения бинарных данных в желаемой кодировке.
Каждый текстовый набор символов (CHARACTER SET) имеет последовательность сортировки (COLLATE) по умолчанию, задающий порядок сортировки и способы сравнения. Если необходимо нестандартное поведение строк при указанных выше действиях, то в описании строкового столбца может быть указан параметр COLLATE, который его опишет. Помимо описания объявления столбца, выражение COLLATE может быть добавлено в предложениях SELECT в секции WHERE, когда происходят операции сравнения больше — меньше, в секции ORDER BY при сортировке по символьному полю, а также при операциях группировки для указания специальной последовательности сортировки при выводе в предложении GROUP BY.
Для регистронезависимого поиска можно воспользоваться функцией UPPER:
WHERE UPPER(name) = UPPER(:flt_name)
Для строк с набором символов WIN1251 можно для этих же целей воспользоваться предложением COLLATE PXW_CYRL.
Пример:
WHERE FIRST_NAME COLLATE PXW_CYRL >= :FLT_NAME
Пример сортировки независимой от регистра символов:
ORDER BY NAME COLLATE PXW_CYRL
См. также: CONTAINING.
Ниже приведена таблица возможных последовательностей сортировки для набора символов UTF8.
Таблица 2.5. Последовательности сортировки для UTF8
COLLATION | Комментарии |
---|---|
UCS_BASIC | Сортировка работает в соответствии с положением символа в таблице (бинарная): Пример: A, B, a, b, a... |
UNICODE | Сортировка работает в соответствии с алгоритмом UCA (Unicode Collation Algorithm) (алфавитная). Пример: a, A, a, b, B... |
UTF-8 | Сортировка происходит без учёта регистра символа. |
UNICODE_CI_AI | Сортировка происходит без учёта регистра символа, в алфавитном порядке. |
Пример сортировки строк для набора символов UTF8 без учёта регистра символов (эквивалент COLLATE PXW_CYRL)
ORDER BY NAME COLLATE UNICODE_CI_AI
При построении индекса по строковым полям необходимо учитывать ограничение на длину ключа индекса. Максимальная используемая длина ключа индекса равна 1/4 размера страницы, т.е. от 1024 до 4096 байтов. Максимальная длина индексируемой строки на 9 байтов меньше, чем максимальная длина ключа. В таблице приведены данные для максимальной длины индексируемой строки (в символах) в зависимости от размера страницы и набора символов, её можно вычислить по следующей формуле:
max_char_length
= FLOOR((page_size
/ 4 – 9) /N
),
где N
— число байтов на представление символа.
Таблица 2.6. Длина индексируемой строки и набор символов
Размер страницы | Максимальная длина индексируемой строки для набора символов, байт/символ | ||||
---|---|---|---|---|---|
1 | 2 | 3 | 4 | 6 | |
4096 | 1015 | 507 | 338 | 253 | 169 |
8192 | 2039 | 1019 | 679 | 509 | 339 |
16384 | 4087 | 2043 | 1362 | 1021 | 682 |
В кодировках, нечувствительных к регистру ("_CI"), один символ в *индексе* будет занимать не 4, а 6 (шесть) байт, поэтому максимальная длина ключа для страницы, скажем, 4096 байт, составит 169 символов.
Последовательность сортировки (COLLATE) тоже может повлиять на максимальную длину индексируемой строки. Полный список доступных наборов символов и нестандартных порядков сортировки доступен в приложении Наборы символов и порядки сортировки.
CHAR является типом данных фиксированной длины. Если введённое количество символом меньше объявленной длины, то поле дополнится концевыми пробелами. В общем случае символ заполнитель может и не являться пробелом, он зависит от набора символов, так например, для набора символов OCTETS — это ноль.
Полное название типа данных CHARACTER, но при работе нет необходимости использовать полные наименования; инструменты по работе с базой прекрасно понимают и короткие имена символьных типов данных.
Синтаксис:
CHAR [(length
)] [CHARACTER SET<charset>
] [COLLATE<collate>
]
В случае если не указана длина, то считается, что она равна единице.
Данный тип символьных данных можно использовать для хранения в справочниках кодов, длина которых стандартна и определённой «ширины». Примером такого может служить почтовый индекс в России – 6 символов.
Является базовым строковым типом для хранения текстов переменной длины, поэтому реальный размер хранимой структуры равен фактическому размеру данных плюс 2 байта, в которых задана длина поля.
Все символы, которые передаются с клиентского приложения в базу данных, считаются как значимые, включая начальные и конечные пробельные символы.
Полное название CHARACTER VARYING. Имеется и сокращённый вариант записи CHAR VARYING.
Синтаксис:
VARCHAR (length
) [CHARACTER SET<charset>
] [COLLATE<collate>
]
Представляет собой символьный тип данных фиксированной длины с предопределённым набором символов ISO8859_1.
Синтаксис:
NCHAR [(length
)]
Синонимом является написание NATIONAL CHAR.
Аналогичный тип данных доступен для строкового типа переменной длины: NATIONAL CHARACTER VARYING.
Строковые литералы могут содержать произвольные символы, допустимые для применяемого набора символов. Весь литерал заключается в апострофы. Апостроф внутри символьного литерала должен повторяться два раза, чтобы отличить его от признака завершения литерала. Максимальная длина строкового литерала составляет 65535 Байт.
Необходимо быть осторожным с длиной строки, если значение должно быть записано в столбец типа VARCHAR. Максимальная длина строки для типа VARCHAR составляет 32765 байт (32767 для типа CHAR). Если значение должно быть записано в столбец типа BLOB, то максимальная длина строкового литерала составляет 65535 байт.
Примеры строковых констант:
'Mrs. Hunt''s husband'
BLOB (Binary Large Objects, большие двоичные объекты) представляют собой сложные структуры, предназначенные для хранения текстовых и двоичных данных неопределённой длины, зачастую очень большого объёма.
Синтаксис:
BLOB [SUB_TYPE<subtype>
] [SEGMENT SIZE<seg_length>
] [CHARACTER SET<charset>
]
Сокращённый синтаксис:
BLOB (<seg_length>
) BLOB (<seg_length>
,<subtype>
) BLOB (,<subtype>
)
Размер сегмента: Указание размера сегмента BLOB является некоторым атавизмом, оно идёт с тех времён, когда приложения для работы с данными BLOB писались на C (Embedded SQL) при помощи GPRE. В настоящий момент размер сегмента при работе с данными BLOB определяется клиентской частью, причём размер сегмента может превышать размер страницы данных.
Подтип BLOB отражает природу данных, записанную в столбце. Firebird предоставляет два предопределённых подтипа для сохранения пользовательских данных:
Подтип 0 (BINARY): Если подтип не указан, то данные считаются нетипизированными и значение подтипа принимается равным 0. Псевдоним подтипа 0 — BINARY. Этот подтип указывает, что данные имеют форму бинарного файла или потока (изображение, звук, видео, файлы текстового процессора, PDF и т.д.).
Подтип 1 (TEXT): Подтип 1 имеет псевдоним TEXT, который может быть использован вместо указания номера подтипа. Например, BLOB SUBTYPE TEXT. Это специализированный подтип, который используется для хранения текстовых данных большого объёма. Для текстового подтипа BLOB может быть указан набор символов и порядок сортировки COLLATE, аналогично символьному полю.
Кроме того, существует возможность добавления пользовательских подтипов данных, для них зарезервирован интервал от -1 до -32768. Пользовательские подтипы с положительными числами не поддерживаются, поскольку Firebird использует числа больше 2 для внутренних подтипов метаданных.
Максимальный размер поля BLOB ограничен 4Гб и не зависит от варианта сервера, 32 битный или 64 битный (во внутренних структурах, связанных с BLOB присутствуют 4-х байтные счётчики). Для размера страницы 4096 максимальный размер BLOB поля несколько ниже 2 Гб.
Текстовые BLOB любой длины и с любым набором символов (включая multi-byte) могут быть использованы практически c любыми встроенными функциями и операторами:
Полная поддержка для операторов:
= (присвоение); |
=, <>, <, <=, >, >= (сравнение); |
|| (конкатенация); |
BETWEEN, IS [NOT] DISTINCT FROM, IN, ANY|SOME и ALL; |
Частичная поддержка для STARTING [WITH], LIKE и CONTAINING. (возникает ошибка, в случае если второй аргумент больше или равен 32 Кб);
SELECT DISTINCT, ORDER BY и GROUP BY в своей работе используют BLOB ID, а не содержимое самого поля. Это одновременно и хорошо и плохо, кроме того, SELECT DISTINCT ошибочно выдаёт несколько значений NULL, если они присутствуют. GROUP BY ведёт себя странно в том, что он объединяет одинаковые строки, если они находятся рядом, но не делает этого, если они располагаются вдали друг от друга.
Хранение BLOB:
По умолчанию, для каждого BLOB создаётся обычная запись, хранящаяся на какой-то выделенной для этого странице данных (data page). Если весь BLOB на эту страницу поместится, его называют BLOB уровня 0. Номер этой специальной записи хранится в записи таблицы и занимает 8 байт.
Если BLOB не помещается на одну страницу данных (data page), то его содержимое размещается на отдельных страницах, целиком выделенных для него (blob page), а в записи о BLOB помещают номера этих страниц. Это BLOB уровня 1.
Если массив номеров страниц с данными BLOB не помещается на страницу данных (data page), то его (массив) размещают на отдельных страницах (blob page), а в запись о BLOB помещают уже номера этих страниц. Это BLOB уровня 2.
Уровни выше 2 не поддерживаются.
См. также: FILTER, DECLARE FILTER.
Поддержка массивов в СУБД Firebird является расширением традиционной реляционной модели. Поддержка в СУБД такого инструмента позволяет проще решать некоторые задачи по обработке однотипных данных. Массивы в Firebird реализованы на базе полей типа BLOB. Массивы могут быть одномерными и многомерными.
CREATE TABLE SAMPLE_ARR (
ID INTEGER NOT NULL PRIMARY KEY,
ARR_INT INTEGER [4]);
Так будет создана таблица с полем типа массива из четырёх целых. Индексы данного массива от 1 до 4. Для определения верхней и нижней границы значений индекса следует воспользоваться следующим синтаксисом:
[<нижняя>
:<верхняя>
]
Добавление новой размерности в синтаксисе идёт через запятую. Пример создания таблицы с массивом размерности два, в котором нижняя граница значений начинается с нуля:
CREATE TABLE SAMPLE_ARR2 ( ID INTEGER NOT NULL PRIMARY KEY, ARR_INT INTEGER [0:3, 0:3]);
СУБД не предоставляет большого набора инструментов для работы с содержимым
массивов. База данных employee.fdb
, которая находится в
дистрибутиве Firebird, содержит пример хранимой процедуры, показывающей возможности
работы с массивами. Ниже приведён её текст:
CREATE OR ALTER PROCEDURE SHOW_LANGS ( CODE VARCHAR(5), GRADE SMALLINT, CTY VARCHAR(15)) RETURNS ( LANGUAGES VARCHAR(15)) AS DECLARE VARIABLE I INTEGER; BEGIN I = 1; WHILE (I <= 5) DO BEGIN SELECT LANGUAGE_REQ[:I] FROM JOB WHERE (JOB_CODE = :CODE) AND (JOB_GRADE = :GRADE) AND (JOB_COUNTRY = :CTY) AND (LANGUAGE_REQ IS NOT NULL)) INTO :LANGUAGES; IF (:LANGUAGES = '') THEN /* PRINTS 'NULL' INSTEAD OF BLANKS */ LANGUAGES = 'NULL'; I = I +1; SUSPEND; END END
Если приведённых выше возможностей достаточно для ваших задач, то вы вполне можете применять массивы для своих проектов. В настоящее время совершенствования механизмов обработки массивов средствами СУБД не производится.
Данный тип данных содержит не данные, а только состояние: NULL или NOT NULL. Также, этот тип данных не может быть использован при объявлении полей таблицы, переменных PSQL, использован в описании параметров. Этот тип данных добавлен для улучшения поддержки нетипизированных параметров в предикате IS NULL. Такая проблема возникает при использовании «отключаемых фильтров» при написании запросов следующего типа:
WHERE col1 = :param1 OR :param1 IS NULL
после обработки, на уровне API запрос будет выглядеть как
WHERE col1 = ? OR ? IS NULL
В данном случае получается ситуация, когда разработчик при написании SQL запрос
рассматривает :param1
как одну переменную, которую
использует два раза, а на уровне API запрос содержит два отдельных и независимых
параметра. Вдобавок к этому, сервер не может определить тип второго параметра,
поскольку он идёт в паре с IS NULL.
Именно для решения проблемы «? IS NULL» и был добавлен этот специальный тип данных SQL_NULL.
После введения данного специального типа данных при передаче запроса и его параметров на сервер будет работать такая схема: приложение передаёт параметризованные запросы на сервер в виде «?». Это делает невозможным слияние пары «одинаковых» параметров в один. Так, например, для двух фильтров (двух именованных параметров) необходимо передать четыре позиционных параметра (далее предполагается, что читатель имеет некоторое знакомство с Firebird API):
SELECT SH.SIZE, SH.COLOUR, SH.PRICE FROM SHIRTS SH WHERE (SH.SIZE = ? OR ? IS NULL) AND (SH.COLOUR = ? OR ? IS NULL)
После выполнения isc_dsql_describe_bind() sqltype 2-го и 4-го параметров устанавливается в SQL_NULL. Как уже говорилось выше, сервер Firebird не имеет никакой информации об их связи с 1-м и 3-м параметрами — это полностью прерогатива программиста. Как только значения для 1-го и 3-го параметров были установлены (или заданы как NULL) и запрос подготовлен, каждая пара XSQLVARs должна быть заполнена следующим образом:
Пользователь задал параметры:
Первый параметр (сравнение значений): set *sqldata в переданное значение и *sqlind в 0 (для NOT NULL);
Второй параметр (проверка на NULL): set *sqldata в NULL (не SQL_NULL) и *sqlind в 0 (для NOT NULL).
Пользователь задал параметры:
Оба параметра (проверка на NULL): set *sqldata в NULL (не SQL_NULL) и *sqlind в -1 (индикация NULL).
Другими словами: значение параметра сравнения всегда устанавливается как обычно. SQL_NULL параметр устанавливается также, за исключением случая, когда sqldata передаётся как NULL.
При написании выражения или при задании, например, условий сравнения, нужно стараться использовать совместимые типы данных. В случае необходимости использования смешанных данных различных типов, желательно первоначально выполнить преобразования типов, а уже потом выполнять операции.
При рассмотрении вопроса преобразования типов в Firebird большое внимание стоит уделить тому, в каком диалекте база данных.
В тех случаях, когда требуется выполнить явное преобразование одного типа в другой, используют функцию CAST.
Синтаксис:
CAST (<value>
| NULL AS<data_type>
)<data_type>
::=sql_datatype
| [TYPE OF]domain
| TYPE OF COLUMNrelname.colname
При преобразовании к домену учитываются объявленные для него ограничения,
например, NOT NULL или описанные в CHECK и если
<value>
не пройдёт проверку, то
преобразование не удастся. В случае если дополнительно указывается TYPE OF
(преобразование к базовому типу), при преобразовании игнорируются любые
ограничения домена. При использовании TYPE OF с типом (VAR)CHAR набор символов и
сортировка сохраняются.
При преобразовании к типу столбца допускается использовать указание столбца таблицы или представления. Используется только сам тип столбца; в случае строковых типов это также включает набор символов, но не сортировку. Ограничения и значения по умолчанию исходного столбца не применяются.
Примеры:
CREATE TABLE TTT ( S VARCHAR (40) CHARACTER SET UTF8 COLLATE UNICODE_CI_AI); COMMIT; /* У меня много друзей (шведский)*/ SELECT CAST ('Jag har manga vanner' AS TYPE OF COLUMN TTT.S) FROM RDB$DATABASE;
Таблица 2.7. Допустимые преобразования для функции CAST
Из типа | В тип | ||||||||
---|---|---|---|---|---|---|---|---|---|
|
|
||||||||
|
|
||||||||
|
|
||||||||
|
|
При преобразовании типов следует помнить о возможной частичной потери данных, например, при преобразовании типа данных TIMESTAMP в DATE.
Для преобразования строковых типов данных в типы DATE, TIME или TIMESTAMP необходимо чтобы строковый аргумент был либо одним из предопределённых литералов даты и времени, либо строковое представление даты в одном из разрешённых форматов.
<datetime_literal>
::= { [YYYY
<p>
]MM
<p>
DD
[<p>
HH
[<p>
mm
[<p>
SS
[<p>
NNNN
]]]] |MM
<p>
DD
[<p>
YYYY
[<p>
HH
[<p>
mm
[<p>
SS
[<p>
NNNN
]]]]] |DD
<p>
MM
[<p>
YYYY
[<p>
HH
[<p>
mm
[<p>
SS
[<p>
NNNN
]]]]] |MM
<p>
DD
[<p>
YY
[<p>
HH
[<p>
mm
[<p>
SS
[<p>
NNNN
]]]]] |DD
<p>
MM
[<p>
YY
[<p>
HH
[<p>
mm
[<p>
SS
[<p>
NNNN
]]]]] | NOW | TODAY | TOMORROW | YERSTERDAY }<date_literal>
::= { [YYYY
<p>
]MM
<p>
DD
|MM
<p>
DD
[<p>
YYYY
] |DD
<p>
MM
[<p>
YYYY
] |MM
<p>
DD
[<p>
YY
] |DD
<p>
MM
[<p>
YY
] | TODAY | TOMORROW | YERSTERDAY }<time_literal>
:=HH
[<p>
mm
[<p>
SS
[<p>
NNNN
]]]<p>
::=whitespace
| . | : | , | - | /
Таблица 2.8. Описание формата даты и времени
Аргумент | Описание |
---|---|
datetime_literal | Литерал даты-времени. |
date_literal | Литерал даты. |
time_literal | Литерал времени. |
YYYY | Год из четырёх цифр. |
YY | Последние две цифры года (00-99). |
MM | Месяц. Может содержать 1 или 2 цифры (1-12 или 01-12). В качестве месяца допустимо также указывать трёхбуквенное сокращение или полное наименование месяца на английском языке, регистр не имеет значение. |
DD | День. Может содержать 1 или 2 цифры (1-31 или 01-31). |
HH | Час. Может содержать 1 или 2 цифры (0-23 или 00-23). |
mm | Минуты. Может содержать 1 или 2 цифры (0-59 или 00-59). |
SS | Секунды. Может содержать 1 или 2 цифры (0-59 или 00-59). |
NNNN | Десятитысячные доли секунды. Может содержать от 1 до 4 цифр (0-9999). |
p | Разделитель, любой из разрешённых символов, лидирующие и завершающие пробелы игнорируются |
Таблица 2.9. Литералы с предопределёнными значениями даты и времени
Литерал | Значение | Тип данных для диалекта 1 | Тип данных для диалекта 3 |
---|---|---|---|
'NOW'
|
Текущая дата и время | DATE | TIMESTAMP |
'TODAY'
|
Текущая дата | DATE (c нулевым временем) | DATE (только дата) |
'TOMORROW'
|
Завтрашняя дата | DATE (c нулевым временем) | DATE (только дата) |
'YESTERDAY'
|
Вчерашняя дата | DATE (c нулевым временем) | DATE (только дата) |
Правила:
В формате Год-Месяц-День, год обязательно должен содержать 4 цифры;
Для дат в формате с завершающим годом, если в качестве разделителя дат используется точка «.», то дата интерпретируется в форме День-Месяц-Год, для остальных разделителей она интерпретируется в форме Месяц-День-Год;
Если год не указан, то в качестве года берётся текущий год;
Если указаны только две цифры года, то для получения столетия Firebird использует алгоритм скользящего окна. Задача заключается в интерпретации двухсимвольного значения года как ближайшего к текущему году в интервале предшествующих и последующих 50 лет;
Если не указан один из элементов времени, то оно принимается равным 0.
Настоятельно рекомендуем в литералах дат использовать только формы с полным указанием года в виде 4 цифр во избежание путаницы.
Примеры интерпретации литералов дат и времени:
SELECT CAST('04.12.2014' AS DATE) AS d1, -- DD.MM.YYYY CAST('04 12 2014' AS DATE) AS d2, -- MM DD YYYY CAST('4-12-2014' AS DATE) AS d3, -- MM-DD-YYYY CAST('04/12/2014' AS DATE) AS d4, -- MM/DD/YYYY CAST('04,12,2014' AS DATE) AS d5, -- MM,DD,YYYY CAST('04.12.14' AS DATE) AS d6, -- DD.MM.YY -- DD.MM в качестве года берётся текущий CAST('04.12' AS DATE) AS d7, -- MM/DD в качестве года берётся текущий CAST('04/12' AS DATE) AS d8, CAST('2014/12/04' AS DATE) AS d9, -- YYYY/MM/DD CAST('2014 12 04' AS DATE) AS d10, -- YYYY MM DD CAST('2014.12.04' AS DATE) AS d11, -- YYYY.MM.DD CAST('2014-12-04' AS DATE) AS d12, -- YYYY-MM-DD CAST('4 Jan 2014' AS DATE) AS d13, -- DD MM YYYY CAST('2014 Jan 4' AS DATE) AS dt14, -- YYYY MM DD CAST('Jan 4, 2014' AS DATE) AS dt15, -- MM DD, YYYY CAST('11:37' AS TIME) AS t1, -- HH:mm CAST('11:37:12' AS TIME) AS t2, -- HH:mm:ss CAST('11:31:12.1234' AS TIME) AS t3, -- HH:mm:ss.nnnn CAST('11.37.12' AS TIME) AS t4, -- HH.mm.ss -- DD.MM.YYYY HH:mm CAST('04.12.2014 11:37' AS TIMESTAMP) AS dt1, -- MM/DD/YYYY HH:mm:ss CAST('04/12/2014 11:37:12' AS TIMESTAMP) AS dt2, -- DD.MM.YYYY HH:mm:ss.nnnn CAST('04.12.2014 11:31:12.1234' AS TIMESTAMP) AS dt3, -- MM/DD/YYYY HH.mm.ss CAST('04/12/2014 11.37.12' AS TIMESTAMP) AS dt4 FROM rdb$database
См. также: CAST, Литералы даты и времени.
В 3-м диалекте невозможно неявное преобразование данных, здесь требуется указывать функцию CAST для явной трансляции одного типа в другой. Однако это не относится к операции конкатенации, при которой все другие типы данных будут неявно преобразованы к символьному.
При использовании 1-го диалекта во многих выражениях выполняется неявное преобразование одних типов в другой без применение функции CAST. Например, в выражении отбора в диалекте 1 можно записать:
WHERE DOC_DATE < '31.08.2014'
и преобразование строки в дату произойдёт неявно.
В 1-м диалекте можно смешивать целые данные и числовые строки, строки неявно преобразуются в целое, если это будет возможно, например:
2 + '1'
корректно выполнится. В 3-м диалекте подобное выражение вызовет ошибку, в нем потребуется запись следующего вида:
2 + CAST('1' AS SMALLINT)
При конкатенации множества элементов разных типов, все не строковые данные будут неявно преобразованы к строке, если это возможно.
Примеры:
SELECT 30||' days hath September, April, June and November' CONCAT$ FROM RDB$DATABASE
CONCAT$ ------------------------------------------------ 30 days hath September, April, June and November
Домены в СУБД Firebird реализуют широко известный по многим языкам программирования инструмент «типы данных, определённые пользователем». Когда несколько таблиц в базе данных содержат поля с характеристиками одинаковыми или практически одинаковыми, то есть целесообразность сделать домен, в котором описать набор свойств поля и использовать такой набор свойств, описанный один раз, в нескольких объектах базы данных. Домены могут использоваться помимо описания полей таблиц и представлений (VIEW) и при объявлении входных и выходных параметров, а также при объявлении переменных в коде PSQL.
Определение домена содержит обязательные и необязательные атрибуты. К обязательному атрибуту относится тип данных. К необязательным относятся:
значение по умолчанию;
возможности использования NULL для домена;
ограничения CHECK для данных домена;
набор символов (для символьных типов данных и BLOB полей);
порядок сортировки (для символьных типов данных).
Пример создания домена:
CREATE DOMAIN BOOL3 AS SMALLINT CHECK (VALUE IS NULL OR VALUE IN (0, 1));
См. также: Явное преобразование типов данных, где описаны отличия работы механизма преобразования данных при указании доменов для опций TYPE OF и TYPE OF COLUMN.
При описании таблиц базы данных некоторые свойства столбцов, базирующихся на доменах, могут быть переопределены. Возможности переопределения атрибутов столбцов на базе доменов приведены в таблице.
Таблица 2.10. Возможности переопределения атрибутов столбцов на базе доменов
Атрибут | Переопределяется? | Примечания |
---|---|---|
тип данных | нет | |
значение по умолчанию | да | |
текстовый набор символов | да | также может использоваться, чтобы восстановить для столбца значения по умолчанию для базы данных |
текстовый порядок сортировки | да | |
условия проверки CHECK | нет | для добавления в проверку новых условий, можно использовать в операторах CREATE и ALTER на уровне таблицы соответствующие предложения CHECK. |
NOT NULL | нет | во многих случаях лучше оставить при описании домена возможность значения NULL, а контроль его допустимости осуществлять в описании полей на уровне таблицы. |
Создание домена производится оператором CREATE DOMAIN.
Краткий синтаксис:
CREATE DOMAIN<name>
[AS]<type>
[DEFAULT {<const>
|<literal>
| NULL |<context_var>
}] [NOT NULL] [CHECK (<condition>
)] [COLLATE collation];
См. также: CREATE DOMAIN.
Для редактирования свойств домена используют оператор ALTER DOMAIN языка определения данных (DDL).
При редактировании домена можно:
переименовать домен;
изменить тип данных;
удалить текущее значение по умолчанию;
установить новое значение по умолчанию;
удалить текущее ограничение CHECK;
добавить новое ограничение CHECK.
Краткий синтаксис:
ALTER DOMAINname
[{TOnew_name
}] [{SET DEFAULT {literal
| NULL |<context_var>
} | DROP DEFAULT}] [{ADD [CONSTRAINT] CHECK (<dom_condition>
) | DROP CONSTRAINT}] [{TYPE<datatype>
}];
Пример:
ALTER DOMAIN STORE_GRP SET DEFAULT -1;
При изменении доменов следует учитывать и его зависимости: имеются ли столбцы таблиц; находятся ли в коде PSQL объявления переменных, входных и/или выходных параметров с типом этого домена. При поспешном редактировании без внимательной проверки можно сделать данный код неработоспособным!
При смене в домене типа данных не допустимы преобразования, которые могут привести к потере данных. Также, например, при преобразовании VARCHAR в INTEGER проверьте, все ли данные, что используют данных домен, смогут пройти преобразование.
См. также: ALTER DOMAIN.
Оператор DROP DOMAIN удаляет из базы данных домена при условии, что он не используется в каком либо из объектов базы данных.
Синтаксис:
DROP DOMAIN name
;
Пример:
DROP DOMAIN Test_Domain;
См. также: DROP DOMAIN.
В этой главе рассматриваются элементы, которые являются общими для всех реализаций языка SQL — выражения, которые используются для извлечения и работают на утверждениях о данных, и предикатов, которые проверяют истинность этих утверждений.
Выражения SQL представляют формальные методы для вычисления, преобразования и сравнения значений. Выражения SQL могут включать в себя столбцы таблиц, переменные, константы, литералы, различные операторы и предикаты, а так же другие выражения. Полный список допустимых символов (tokens) в выражениях описан ниже.
Таблица 3.1. Описание элементов языка
Элемент | Описание |
---|---|
Имя столбца | Идентификаторы столбцов из указанных таблиц, используемые в вычислениях, или сравнениях, или в качестве условия поиска. Столбец типа массив не может быть элементом выражения, если только он не проверяется на IS [NOT] NULL. |
Элементы массива | В выражении может содержаться ссылка на элемент массива, т.е.
<array_name>[s] , где
s — индекс элемента в массиве
<array_name> .
|
Арифметические операторы | Символы +, -, *, / используемые для вычисления значений. |
Оператор конкатенации | Оператор || используется для соединения символьных строк. |
Логические операторы | Зарезервированные слова NOT, AND и OR используются при комбинировании простых условий поиска для создания сложных утверждений. |
Операторы сравнения | Символы =, <>, !=, ~=, ^=, <, <=, >, >=, !<, ~<, ^<, !>, ~> и ^>. |
Предикаты сравнения | LIKE, STARTING WITH, CONTAINING, SIMILAR TO, BETWEEN, IS [NOT] NULL и IS [NOT] DISTINCT FROM |
Предикаты существования | Предикаты, используемые для проверки существования значений в наборе. Предикат IN может быть использован как с наборами констант, так и со скалярными подзапросами. Предикаты EXISTS, SINGULAR, ALL ANY, SOME могут быть использованы только с подзапросами. |
Константы | Числа, заключённые в апострофы строковые литералы, псевдозначение NULL. |
Литералы дат | Выражения, подобные строковым литералам, заключённые в апострофах, которые могут быть интерпретированы как значения даты, времени или даты-времени. Литералами дат могут быть предварительно объявленные литералы ('TODAY', 'NOW' и т.д.) или строки из символов и чисел, такие как '25.12.2016 15:30:35', которые могут быть преобразованы в дату, время или дату с временем. |
Контекстные переменные | Встроенные контекстные переменные. |
Локальные переменные | Локальные переменные, входные или выходные параметры PSQL модулей (хранимых процедур, триггеров, анонимных блоков PSQL). |
Позиционные параметры | В DSQL в качестве параметров запроса могут быть использованы только позиционные параметры. Позиционные параметры представляют собой знаки вопроса (?) внутри DSQL оператора. Доступ к таким параметрам осуществляется по его номеру (позиции в запросе относительно предыдущего позиционного параметра) поэтому они называются позиционными. Обычно компоненты доступа позволяют работать с именованными параметрами, которые они сами преобразовывают в позиционные. |
Подзапросы | Оператор SELECT заключённый в круглые скобки, который возвращает одно единственное (скалярное) значение или множество значений (при использовании в предикатах существования). |
Идентификаторы функций | Идентификаторы встроенных или внешних функций в функциональных выражениях. |
Приведения типа |
Выражение явного преобразования одного типа данных в другой CAST( или сокращённое (для даты/времени) преобразование типа
например |
Условные выражения | Выражение CASE и встроенные функции COALESCE, NULLIF. |
Круглые скобки | Пара скобок ( ... ) используются для группировки выражений. Операции внутри скобок выполняются перед операциями вне скобок. При использовании вложенных скобок, сначала вычисляются значения самых внутренних выражений, а затем вычисления перемещаются наверх по уровням вложенности. |
Предложение COLLATE | Предложение применяется к типам CHAR и VARCHAR, чтобы в указанной кодировке установить параметры сортировки, используемые при сравнении. |
NEXT VALUE FOR
sequence |
Конструкция NEXT VALUE FOR позволяет получить следующее значение последовательности, то же самое делает встроенная функция GEN_ID(). |
Константа это значение, подставляемое непосредственно в SQL оператор, которое не получено из выражения, параметра, ссылки на столбец или переменной. Константой может быть строка или число.
Строковая константа это последовательность символов, заключенных между парой апострофов («одинарных кавычек»). Максимальная длина строковой константы составляет 32767 байт; максимальная количество символов будет определяться количеством байт, используемых для кодирования каждого символа.
Двойные кавычки не должны (допускаются 1 диалектом) использоваться для квотирования строк. В SQL они предусмотрены для других целей.
Если литерал апострофа требуется в строковой константе, то он может быть «экранирован» другим предшествующим апострофом. Например,
'Mother O''Reilly's home-made hooch'
Необходимо быть осторожным с длиной строки, если значение должно быть записано в столбец типа VARCHAR. Максимальная длина строки для типа VARCHAR составляет 32765 байт.
Предполагается, что набор символов строковой константы совпадает с набором символов столбца предназначенного для её сохранения.
Начиная с Firebird 2.5 строковые константы могут быть записаны в шестнадцатеричной нотации, так называемые «двоичные строки». Каждая пара шестнадцатеричных цифр определяет один байт в строке. Строки введённые таким образом будут иметь кодировку OCTETS по умолчанию, но вводный синтаксис (introducer syntax) может быть использован для принудительной интерпретации строки в другом наборе символов.
Синтаксис:
{x|X}'<hexstring>
'<hexstring>
::= an even number of<hexdigit>
<hexdigit>
::= 0..9 | A..F | a..f
Примеры:
SELECT x'4E657276656E' FROM rdb$database -- returns 4E657276656E, a 6-byte 'binary' string SELECT _ascii x'4E657276656E' FROM rdb$database -- returns 'Nerven' (same string, now interpreted as ASCII text) SELECT _iso8859_1 x'53E46765' FROM rdb$database -- returns 'Säge' (4 chars, 4 bytes) SELECT _utf8 x'53C3A46765' FROM rdb$database -- returns 'Säge' (4 chars, 5 bytes)
Как будут отображены двоичные строки зависит от интерфейса клиента. Например, утилита isql использует заглавные буквы A-F, в то время как FlameRobin буквы в нижнем регистре. Другие могут использовать другие правила конвертирования, например, отображать пробелы между парами байт: '4E 65 72 76 65 6E'.
Шестнадцатеричная нотация позволяет вставить любой байт (включая 00) в любой позиции в строке.
При необходимости, строковому литералу может предшествовать имя набор символов, который начинается с префикса подчеркивания «_». Это известно как вводный синтаксис (Introducer syntax). Его цель заключается в информировании Firebird о том, как интерпретировать и хранить входящую строку.
Примеры:
-- обратите внимание на префикс '_' INSERT INTO People VALUES (_ISO8859_1 'Hans-Jörg Schäfer');
Числовая константа — это любое правильное число в одной из поддерживаемых нотаций:
В SQL, для чисел в стандартной десятичной записи, десятичная точка всегда представлена символом точки и тысячи не разделены. Включение запятых, пробелов, и т.д. вызовет ошибки.
Экспоненциальная запись, например, число 0.0000234 может быть
записано как 2.34e-5
.
Шестнадцатеричная запись (см. ниже) чисел поддерживается начиная с Firebird 2.5.
Начиная с Firebird 2.5 целочисленные значения могут быть записаны в шестнадцатеричной системе счисления. Числа состоящие из 1-8 шестнадцатеричных цифр будут интерпретированы как INTEGER, состоящие из 9-16 цифр — как BIGINT.
Синтаксис:
{x|X}<hexdigits>
<hexdigits>
::= 1-16 of<hexdigit>
<hexdigit>
::= 0..9 | A..F | a..f
Примеры:
SELECT 0x6FAA0D3 FROM rdb$database -- returns 117088467 SELECT 0x4F9 FROM rdb$database -- returns 1273 SELECT 0x6E44F9A8 FROM rdb$database -- returns 1850014120 SELECT 0x9E44F9A8 FROM rdb$database -- returns -1639646808 (an INTEGER) SELECT 0x09E44F9A8 FROM rdb$database -- returns 2655320488 (a BIGINT) SELECT 0x28ED678A4C987 FROM rdb$database -- returns 720001751632263 SELECT 0xFFFFFFFFFFFFFFFF FROM rdb$database -- returns -1
Шестнадцатеричные числа в диапазоне 0 .. 7FFF FFFF являются положительными INTEGER числа со значениями 0 .. 2147483647. Для того, чтобы интерпретировать константу как BIGINT число необходимо дописать необходимо количества нулей слева. Это изменит тип, но не значение.
Числа в диапазоне 8000 0000 .. FFFF FFFF требуют особого внимания:
При записи восемью шестнадцатеричный числами, такие как 0x9E44F9A8, интерпретируется как 32-битное целое. Поскольку крайний левый (знаковый) бит установлен, то такие числа будут находится в отрицательном диапазоне -2147483648 .. -1.
Числа предварённые одним или несколькими нулями, такие как 0x09E44F9A8, будут интерпретированы как 64-разрядный BIGINT в диапазоне значений 0000 0000 8000 0000 .. 0000 0000 FFFF FFFF. В этом случае знаковый бит не установлен, поэтому они отображаются в положительном диапазоне 2147483648 .. 4294967295 десятичных чисел.
Таким образом, только в этом диапазоне числа, предварённые совершенно незначимым нулём, имеют кардинально разные значения. Это необходимо знать.
Шестнадцатеричные числа в диапазоне 1 0000 0000 .. 7FFF FFFF FFFF FFFF являются положительными BIGINT числами.
Шестнадцатеричные числа в диапазоне 8000 0000 0000 0000 .. FFFF FFFF FFFF FFFF являются отрицательными BIGINT числами.
Числа с типом SMALLINT не могут быть записаны в шестнадцатеричном виде, строго говоря, так как даже 0x1 оценивается как INTEGER. Тем не менее, если вы записываете положительное целое число в пределах 16-разрядного диапазона от 0x0000 (десятичный ноль) до 0x7FFF (десятичное 32767), то оно будет преобразовано в SMALLINT прозрачно.
Вы можете записать отрицательное SMALLINT число в шестнадцатеричном виде используя 4-байтное шестнадцатеричное число в диапазоне от 0xFFFF8000 (десятичное -32768) до 0xFFFFFFFF (десятичное -1).
SQL операторы включают в себя операторы для сравнения, вычисления, оценки и конкатенации значений.
Приоритет определяет порядок, в котором операторы и получаемые с помощью них значения вычисляются в выражении.
Все операторы разбиты на 4 типа. Каждый тип оператора имеет свой приоритет. Чем выше приоритет типа оператора, тем раньше он будет вычислен. Внутри одного типа операторы имеют собственный приоритет, который также определяет порядок их вычисления в выражении. Операторы с одинаковым приоритетом вычисляются слева направо. Для изменения порядка вычислений операции могут быть сгруппированы с помощью круглых скобок.
Таблица 3.2. Приоритеты типов операторов
Тип оператора | Приоритет | Пояснение |
---|---|---|
Конкатенация | 1 | Строки объединяются до выполнения любых других операций. |
Арифметический | 2 | Арифметические операции выполняются после конкатенации строк, но перед выполнением операторов сравнения и логических операций. |
Сравнение | 3 | Операции сравнения вычисляются после конкатенации строк и выполнения арифметических операций, но до логических операций. |
Логический | 4 | Логические операторы выполняются после всех других типов операторов. |
Оператор конкатенации (||) соединяет две символьные строки и создаёт одну строку. Символьные стоки могут быть константами или значениями, полученными из столбцов или других выражений.
Пример:
SELECT LAST_NAME || ', ' || FIRST_NAME AS FULL_NAME
FROM EMPLOYEE
Таблица 3.3. Приоритет арифметических операторов
Оператор | Назначение | Приоритет |
---|---|---|
+ | Унарный плюс | 1 |
- | Унарный минус | 1 |
* | Умножение | 2 |
/ | Деление | 2 |
+ | Сложение | 3 |
- | Вычитание | 3 |
Пример:
UPDATE T SET A = 4 + 1/(B-C)*D
Таблица 3.4. Операторы сравнения
Оператор | Назначение |
---|---|
= | Равно, идентично |
<>, !=, ~=, ^= | Не равно |
> | Больше |
< | Меньше |
>= | Больше или равно |
<= | Меньше или равно |
!>, ~>, ^> | Не больше |
!<, ~<, ^< | Не меньше |
В эту же группу входят предикаты сравнения IS DISTINCT FROM, BETWEEN, IN, LIKE, CONTAINING, SIMILAR TO и другие.
Пример:
IF (SALARY > 1400) THEN
...
См. также: Другие предикаты сравнения.
Таблица 3.5. Приоритет логических операторов
Оператор | Назначение | Приоритет |
---|---|---|
NOT | Отрицание условия поиска. | 1 |
AND | Объединяет два предиката и более, каждый из которых должен быть истинным, чтобы истинным был и весь предикат. | 2 |
OR | Объединяет два предиката и более, из которых должен быть истинным хотя бы один предикат, чтобы истинным был и весь предикат. | 3 |
Пример:
IF (A > B OR (A > C AND A > D) AND NOT (C = D)) THEN ...
Доступно в: DSQL, PSQL.
Синтаксис:
NEXT VALUE FOR sequence-name
Возвращает следующее значение в последовательности (SEQUENCE). SEQUENCE является SQL совместимым термином генератора в InterBase и Firebird. Оператор NEXT VALUE FOR полностью эквивалентен функции GEN_ID (seq, n) и является рекомендуемым синтаксисом.
Пример:
NEW.CUST_ID = NEXT VALUE FOR CUSTSEQ;
NEXT VALUE FOR не поддерживает значение приращения, отличное от 1. Если требуется другое значение шага, то используйте старую функцию GEN_ID.
См. также: SEQUENCE (GENERATOR), GEN_ID.
Условное выражение — это выражение, которое возвращает различные значения в зависимости от истинности некоторого условия или условий. В данном разделе описано лишь одно условное выражение CASE. Остальные условные выражения являются производными встроенными функциями и описаны в разделе Скалярные функции.
Доступно в: DSQL, ESQL.
Оператор CASE возвращает только одно значение из нескольких возможных. Есть два синтаксических варианта:
Простой CASE, сравнимый с Pascal case или C switch;
Поисковый CASE, который работает как серия операторов if ... else if ... else if.
Синтаксис:
CASE<test-expr>
WHEN<expr>
THEN<result>
[WHEN<expr>
THEN<result>
...] [ELSE<defaultresult>
] END
При использовании этого варианта
<test-expr>
сравнивается с
<expr>
1,
<expr>
2 и т.д. до тех пор, пока не
будет найдено совпадение, и тогда возвращается соответствующий результат.
Если совпадений не найдено, то возвращается
defaultresult
из ветви ELSE. Если нет
совпадений, и ветвь ELSE отсутствует, возвращается значение NULL.
Совпадение эквивалентно оператору «=»,
т.е. если <test-expr>
имеет значение NULL,
то он не соответствует ни одному из <expr>
,
даже тем, которые имеют значение NULL.
Результаты не обязательно должны быть литеральными значениями, они также могут быть именами полей, переменными, сложными выражениями или NULL.
Пример:
SELECT NAME, AGE, CASE UPPER(SEX) WHEN 'M' THEN 'Male' WHEN 'F' THEN 'Female' ELSE 'Unknown' END AS SEXNAME, RELIGION FROM PEOPLE
Сокращённый вид простого оператора CASE используется в функции DECODE.
Синтаксис:
CASE WHEN<bool_expr>
THEN<result>
[WHEN<bool_expr>
THEN<result>
…] [ELSE<defaultresult>
] END
Здесь <bool_expr>
выражение, которое даёт
тройной логический результат: TRUE, FALSE или NULL. Первое выражение,
возвращающее TRUE, определяет результат. Если нет выражений, возвращающих
TRUE, то в качестве результата берётся
defaultresult
из ветви ELSE. Если нет
выражений, возвращающих TRUE, и ветвь ELSE отсутствует, результатом будет
NULL.
Как и в простом операторе CASE, результаты не обязаны быть литеральными значениями: они могут быть полями или именами переменных, сложными выражениями, или NULL.
Пример:
CANVOTE = CASE WHEN AGE >= 18 THEN 'Yes' WHEN AGE < 18 THEN 'No' ELSE 'Unsure' END;
В SQL NULL не является значением — это состояние, указывающее, что значение элемента неизвестно или не существует. Это не ноль, не пустота, не «пустая строка», и оно не ведёт себя как какое-то из этих значений.
При использовании NULL в числовых, строковых выражениях или в выражениях, содержащих дату/время, в результате вы всегда получите NULL. При использовании NULL в логических (булевых) выражениях результат будет зависеть от типа операции и других вовлечённых значений. При сравнении значения с NULL результат будет неопределённым (UNKNOWN).
Неопределённый логический результат (UNKNOWN) тоже представлен псевдо-значением NULL.
Выражения в этом списке всегда возвратят NULL:
1 + 2 + 3 + NULL 'Home ' || 'sweet ' || NULL MyField = NULL MyField <> NULL NULL = NULL not (NULL)
Если вам трудно понять, почему, вспомните, что NULL — значит «неизвестно».
Мы уже рассмотрели, что not (NULL) даёт в результате NULL. Для операторов and (логическое И) и or (логическое ИЛИ) взаимодействие несколько сложнее:
NULL or false = NULL NULL or true = true NULL or NULL = NULL NULL and false = false NULL and true = NULL NULL and NULL = NULL
В Firebird 2.5 не существует логического (булева) типа данных (такой тип введён в Firebird 3.0), тем не менее, существуют логические выражения (предикаты), которые могут возвращать истину, ложь или неизвестно.
Примеры:
(1 = NULL) OR (1 <> 1) -- возвратит NULL (1 = NULL) OR (1 = 1) -- возвратит TRUE (1 = NULL) OR (1 = NULL) -- возвратит NULL (1 = NULL) AND (1 <> 1) -- возвратит FALSE (1 = NULL) AND (1 = 1) -- возвратит NULL (1 = NULL) AND (1 = NULL) -- возвратит NULL
Подзапрос — это специальный вид выражения, которое фактически является запросом SELECT к другой таблице, включённый в спецификацию основного запроса. Подзапросы пишутся как обычные SELECT запросы, но должны быть заключены в круглые скобки. Выражения подзапроса используется следующими способами:
Для задания выходного столбца в списке выбора SELECT;
Для получения значений или условий для предикатов поиска (предложения WHERE, HAVING).
Подзапрос может быть коррелированным (соотнесённым). Запрос называется соотнесённым, когда оба, и внутренний, и внешний, запросы взаимозависимы. Это означает, что для обработки каждой записи внутреннего запроса, должна быть получена также запись внешнего запроса, т.е. внутренний запрос всецело зависит от внешнего.
Пример коррелированного подзапроса:
SELECT *
FROM Customers C
WHERE EXISTS
(SELECT *
FROM Orders O
WHERE C.cnum = O.cnum
AND O.adate = DATE '10.03.1990');
При использовании подзапросов для получения значений выходного столбца в списке выбора SELECT, подзапрос должен возвращать скалярный результат.
Подзапросы, используемые в предикатах поиска, кроме предикатов существования и количественных предикатов, должны возвращать скалярное результат, то есть не более чем один столбец из одной отобранной строки или одно агрегированное значение, в противном случае, произойдёт ошибка времени выполнения («Multiple rows in a singleton select...»).
Примеры:
Пример 3.1. Подзапрос в качестве выходного столбца в списке выбора
SELECT
e.first_name,
e.last_name,
(SELECT
sh.new_salary
FROM
salary_history sh
WHERE
sh.emp_no = e.emp_no
ORDER BY sh.change_date DESC ROWS 1) AS last_salary
FROM
employee e
Пример 3.2. Подзапрос в предложении WHERE для получения значения максимальной зарплаты сотрудника и фильтрации по нему
SELECT e.first_name, e.last_name, e.salary FROM employee e WHERE e.salary = (SELECT MAX(ie.salary) FROM employee ie)
Предикат — это простое выражение, утверждающее некоторый факт. Предикат может быть истинным (TRUE), ложным (FALSE) и неопределённым (UNKNOWN). В SQL ложный и неопределённый результаты трактуются как ложь.
В SQL предикаты проверяют в ограничении CHECK, предложении WHERE, выражении CASE, условии соединения во фразе ON для предложений JOIN, а также в предложении HAVING. В PSQL операторы управления потоком выполнения проверяют предикаты в предложениях IF, WHILE и WHEN.
Проверяемые условия не всегда являются простыми предикатами. Они могут быть группой предикатов, каждый из которых при вычислении делает вклад в вычислении общей истинности. Такие сложные условия называются утверждениями. Утверждения могут состоять из одного или нескольких предикатов, связанных логическими операторами AND, OR и NOT.
Каждый из предикатов может содержать вложенные предикаты. Результат вычисления истинности утверждения получается в результате вычисления всех предикатов по направлению от внутренних к внешним. Каждый «уровень» вычисляется в порядке приоритета, до тех пор, пока невозможно будет получить окончательное утверждение.
Предикат сравнения представляет собой два выражения, соединяемых оператором сравнения. Имеется шесть традиционных операторов сравнения:
=, >, <, >=, <=, <>
(Полный список операторов сравнения см. Операторы сравнения).
Если в одной из частей (левой или правой) предиката сравнения встречается NULL, то значение предиката будет неопределённым (UNKNOWN).
Примеры:
Получить информацию о компьютерах, имеющих частоту процессора не менее 500 МГц и цену ниже $800
SELECT * FROM Pc WHERE speed >= 500 AND price < 800;
Получить информацию обо всех принтерах, которые являются матричными и стоят меньше $300
SELECT * FROM Printer WHERE type = 'matrix' AND price < 300;
Следующий запрос не вернёт ни одной записи, поскольку сравнение происходит с псевдо-значением NULL, даже если существуют принтеры с неуказанным типом.
SELECT *
FROM Printer
WHERE type = NULL AND price < 300;
Другие предикаты сравнения состоят из ключевых слов.
Доступно в: DSQL, PSQL, ESQL.
Синтаксис:
<value>
[NOT] BETWEEN<value_1>
AND<value_2>
Оператор BETWEEN проверяет, попадает (или не попадает при использовании NOT) ли значение во включающий диапазон значений.
Оператор BETWEEN использует два аргумента совместимых типов. В отличие от некоторых других СУБД в Firebird оператор BETWEEN не является симметричным. Меньшее значение должно быть первым аргументом, иначе предикат BETWEEN всегда будет ложным. Поиск является включающим. Таким образом, предикат BETWEEN можно переписать следующим образом:
<value>
>=<value_1>
AND<value>
<=<value_2>
При использовании предиката BETWEEN в поисковых условиях DML запросов, оптимизатор Firebird может использовать индекс по искомому столбцу, если таковой доступен.
SELECT *
FROM EMPLOYEE
WHERE HIRE_DATE BETWEEN date '01.01.1992' AND CURRENT_DATE
Доступно в: DSQL, PSQL, ESQL.
Синтаксис:
<match value>
[NOT] LIKE<pattern>
[ESCAPE<escape character>
]
Таблица 3.6. Параметры предиката LIKE
Параметр | Описание |
---|---|
match value |
Выражение символьного типа. |
pattern |
Шаблон поиска. |
escape character |
Символ экранирования. |
Предикат LIKE сравнивает выражение символьного типа с шаблоном, определённым во втором выражении. Сравнение с шаблоном является чувствительным к регистру (за исключением случаев, когда само поле определено с сортировкой (COLLATION) нечувствительной к регистру).
При использовании оператора LIKE во внимание принимаются все символы строки-шаблона. Это касается так же начальных и конечных пробелов. Если операция сравнения в запросе должна вернуть все строки, содержащие строки LIKE 'абв ' (с символом пробела на конце), то строка, содержащая 'абв' (без пробела), не будет возвращена.
В шаблоне, разрешается использование двух трафаретных символов:
символ процента (%) заменяет последовательность любых символов (число символов в последовательности может быть от 0 и более) в проверяемом значении;
символ подчёркивания (_), который можно применять вместо любого единичного символа в проверяемом значении.
Если проверяемое значение соответствует образцу с учётом трафаретных символов, то предикат истинен.
Если искомая строка содержит трафаретный символ, то следует задать управляющий символ в предложении ESCAPE. Этот управляющий символ должен использоваться в образце перед трафаретным символом, сообщая о том, что последний следует трактовать как обычный символ.
Найти номера отделов, названия которых начинаются со слова «Software»:
SELECT DEPT_NO
FROM DEPT
WHERE DEPT_NAME LIKE 'Software%';
В данном запросе может быть использован индекс, если он построен на поле DEPT_NAME.
В общем случае предикат LIKE не использует индекс. Однако если предикат принимает вид LIKE 'строка%', то он будет преобразован в предикат STARTING WITH, который будет использовать индекс. Если вам необходимо выполнить поиск с начала строки, то вместо предиката LIKE рекомендуется использовать предикат STARTING WITH.
Поиск сотрудников, имена которых состоят из 5 букв, начинающихся с букв «Sm» и заканчивающихся на «th». В данном случае предикат будет истинен для имен «Smith» и «Smyth».
SELECT
first_name
FROM
employee
WHERE first_name LIKE 'Sm_th'
Поиск всех заказчиков, в адресе которых содержится строка «Ростов».
SELECT *
FROM CUSTOMER
WHERE ADDRESS LIKE '%Ростов%'
Если вам необходимо выполнить поиск внутри строки, то вместо предиката LIKE рекомендуется использовать предикат CONTAINING.
Поиск таблиц, содержащих в имени знак подчёркивания. В данном случае в качестве управляющего символа задан символ «#».
SELECT RDB$RELATION_NAME FROM RDB$RELATIONS WHERE RDB$RELATION_NAME LIKE '%#_%' ESCAPE '#'
См. также: STARTING WITH, CONTAINING, SIMILAR TO.
Доступно в: DSQL, PSQL, ESQL.
Синтаксис:
<value>
[NOT] STARTING WITH<value>
Оператор STARTING WITH ищет строку или тип, подобный строке, которая начинается с символов в его аргументе. Поиск STARTING WITH чувствителен к регистру.
При использовании предиката STARTING WITH в поисковых условиях DML запросов, оптимизатор Firebird может использовать индекс по искомому столбцу, если он определён.
Поиск сотрудников, фамилия которых начинается с «Jo».
SELECT LAST_NAME, FIRST_NAME
FROM EMPLOYEE
WHERE LAST_NAME STARTING WITH 'Jo'
См. также: LIKE.
Доступно в: DSQL, PSQL, ESQL.
Синтаксис:
<value>
[NOT] CONTAINING<value>
Оператор CONTAINING ищет строку или тип, подобный строке, отыскивая последовательность символов, которая соответствует его аргументу. Он может быть использован для алфавитно-цифрового (подобного строковому) поиска в числах и датах. Поиск CONTAINING не чувствителен к регистру. Тем не менее, если используется сортировка чувствительная к акцентам, то поиск будет чувствителен к акцентам.
При использовании оператора CONTAINING во внимание принимаются все символы строки. Это касается так же начальных и конечных пробелов. Если операция сравнения в запросе должна вернуть все строки, содержащие строки CONTAINING 'абв ' (с символом пробела на конце), то строка, содержащая 'абв' (без пробела), не будет возвращена.
При использовании предиката CONTAINING в поисковых условиях DML запросов, оптимизатор Firebird не может использовать индекс по искомому столбцу.
Поиск проектов в именах, которых присутствует подстрока «Map»:
SELECT *
FROM PROJECT
WHERE PROJ_NAME CONTAINING 'map';
В данном случае будет возвращены две строки с именами «AutoMap» и «MapBrowser port».
Поиск записей об изменении зарплат с датой содержащей число 84 (в данном случае изменения, которые произошли в 1984 году):
SELECT *
FROM SALARY_HISTORY
WHERE CHANGE_DATE CONTAINING 84;
См. также: LIKE.
Доступно в: DSQL, PSQL.
Синтаксис:
<match value>
[NOT] SIMILAR TO<pattern>
[ESCAPE<escape character>
]
Таблица 3.7. Параметры предиката SIMILAR TO
Параметр | Описание |
---|---|
match value |
Выражение символьного типа. |
pattern |
Регулярное выражение SQL. |
escape character |
Символ экранирования. |
Оператор SIMILAR TO проверяет соответствие строки с шаблоном регулярного выражения SQL. В отличие от некоторых других языков для успешного выполнения шаблон должен соответствовать всей строке — соответствие подстроки не достаточно. Если один из операндов имеет значение NULL, то и результат будет NULL. В противном случае результат является TRUE или FALSE.
Следующий синтаксис определяет формат регулярного выражения SQL. Это полное и корректное его определение. Он является весьма формальным и довольно длинным и, вероятно, озадачивает тех, кто не имеет опыта работы с регулярными выражениями. Не стесняйтесь пропустить его и начать читать следующий раздел, Создание регулярных выражений, использующий подход от простого к сложному.
<regular expression>
::=<regular term>
['|'<regular term>
...]<regular term>
::=<regular factor>
...<regular factor>
::=<regular primary>
[<quantifier>
]<quantifier>
::= ? | * | + | '{'<m>
[,[<n>
]] '}'<m>
,<n>
::= целое положительное число с<m>
<=<n>
если оба присутствуют<regular primary>
::=<character>
|<character class>
| % | (<regular expression>
)<character>
::=<escaped character>
|<non-escaped character>
<escaped character>
::=<escape-char>
<special character>
|<escape-char>
<escape-char>
<special character>
::= любой из символов []()|^-+*%_?{<non-escaped character>
::= любой символ за исключением<special character>
и не эквивалентный<escape-char>
(если задан)<character class>
::= '_' | '['<member>
... ']' | '[^'<non-member>
... ']' | '['<member>
... '^'<non-member>
... ']'<member>
,<non-member>
::=<character>
|<range>
|<predefined class>
<range>
::=<character>
-<character>
<predefined class>
::= '[:'<predefined class name>
':]'<predefined class name>
::= ALPHA | UPPER | LOWER | DIGIT | ALNUM | SPACE | WHITESPACE
В регулярных выражениях большинство символов представляет сами себя, за исключением специальных символов (special character):
[ ] ( ) | ^ - + * % _ ? { }
и управляющих символов, если они заданы.
Регулярному выражению, не содержащему специальных или управляющих символов, соответствует только полностью идентичные строки (в зависимости от используемой сортировки). То есть это функционирует точно так же, как оператор «=»:
'Apple' SIMILAR TO 'Apple' -- TRUE 'Apples' SIMILAR TO 'Apple' -- FALSE 'Apple' SIMILAR TO 'Apples' -- FALSE 'APPLE' SIMILAR TO 'Apple' -- в зависимости от сортировки
Известным SQL шаблонам _ и % соответствует любой единственный символ и строка любой длины, соответственно:
'Birne' SIMILAR TO 'B_rne' -- TRUE 'Birne' SIMILAR TO 'B_ne' -- FALSE 'Birne' SIMILAR TO 'B%ne' -- TRUE 'Birne' SIMILAR TO 'Bir%ne%' -- TRUE 'Birne' SIMILAR TO 'Birr%ne' -- FALSE
Обратите внимание, что шаблон % также соответствует пустой строке.
Набор символов, заключённый в квадратные скобки определяют класс символов. Символ в строке соответствует классу в шаблоне, если символ является элементом класса:
'Citroen' SIMILAR TO 'Cit[arju]oen' -- TRUE 'Citroen' SIMILAR TO 'Ci[tr]oen' -- FALSE 'Citroen' SIMILAR TO 'Ci[tr][tr]oen' -- TRUE
Как видно из второй строки классу только соответствует единственный символ, а не их последовательность.
Два символа, соединённые дефисом, в определении класса определяют диапазон. Диапазон для активного сопоставления включает в себя эти два конечных символа и все символы, находящиеся между ними. Диапазоны могут быть помещены в любом месте в определении класса без специальных разделителей, чтобы сохранить в классе и другие символы.
'Datte' SIMILAR TO 'Dat[q-u]e' -- TRUE 'Datte' SIMILAR TO 'Dat[abq-uy]e' -- TRUE 'Datte' SIMILAR TO 'Dat[bcg-km-pwz]e' -- FALSE
[:ALPHA:]
Латинские буквы a...z и A...Z. Этот класс также включает символы с диакритическими знаками при нечувствительных к акцентам сортировках.
[:DIGIT:]
Десятичные цифры 0...9.
[:ALNUM:]
Объединение [:ALPHA:] и [:DIGIT:].
[:UPPER:]
Прописные (в верхнем регистре) латинские буквы A...Z. Также включает в себя символы в нижнем регистре при нечувствительных к регистру сортировках и символы с диакритическими знаками при нечувствительных к акцентам сортировках.
[:LOWER:]
Строчные (в нижнем регистре) латинские буквы a...z. Также включает в себя символы в верхнем регистре при нечувствительных к регистру сортировках и символы с диакритическими знаками при нечувствительных к акцентам сортировках.
[:SPACE:]
Символ пробела (ASCII 32).
[:WHITESPACE:]
Горизонтальная табуляция (ASCII 9), перевод строки (ASCII 10), вертикальная табуляция (ASCII 11), разрыв страницы (ASCII 12), возврат каретки (ASCII 13) и пробел (ASCII 32).
Включение в оператор SIMILAR TO предопределённого класса имеет тот же эффект, как и включение всех его элементов. Использование предопределённых классов допускается только в пределах определения класса. Если Вам нужно сопоставление только с предопределённым классом и ничего больше, то поместите дополнительную пару скобок вокруг него.
'Erdbeere' SIMILAR TO 'Erd[[:ALNUM:]]eere' -- TRUE 'Erdbeere' SIMILAR TO 'Erd[[:DIGIT:]]eere' -- FALSE 'Erdbeere' SIMILAR TO 'Erd[a[:SPACE:]b]eere' -- TRUE 'Erdbeere' SIMILAR TO '[[:ALPHA:]]' -- FALSE 'E' SIMILAR TO '[[:ALPHA:]]' -- TRUE
Если определение класса запускается со знаком вставки (^), то все, что следует за ним, исключается из класса. Все остальные символы проверяются.
'Framboise' SIMILAR TO 'Fra[^ck-p]boise' -- FALSE 'Framboise' SIMILAR TO 'Fr[^a][^a]boise' -- FALSE 'Framboise' SIMILAR TO 'Fra[^[:DIGIT:]]boise' -- TRUE
Если знак вставки (^) находится не в начале последовательности, то класс включает в себя все символы до него и исключает символы после него.
'Grapefruit' SIMILAR TO 'Grap[a-m^f-i]fruit' -- TRUE 'Grapefruit' SIMILAR TO 'Grap[abc^xyz]fruit' -- FALSE 'Grapefruit' SIMILAR TO 'Grap[abc^de]fruit' -- FALSE 'Grapefruit' SIMILAR TO 'Grap[abe^de]fruit' -- FALSE '3' SIMILAR TO '[[:DIGIT:]^4-8]' -- TRUE '6' SIMILAR TO '[[:DIGIT:]^4-8]' -- FALSE
Наконец, уже упомянутый подстановочный знак «_» является собственным классом символов, соответствуя любому единственному символу.
Вопросительный знак сразу после символа или класса указывает на то, что для соответствия предыдущий элемент должен встретиться 0 или 1 раз:
'Hallon' SIMILAR TO 'Hal?on' -- FALSE 'Hallon' SIMILAR TO 'Hal?lon' -- TRUE 'Hallon' SIMILAR TO 'Halll?on' -- TRUE 'Hallon' SIMILAR TO 'Hallll?on' -- FALSE 'Hallon' SIMILAR TO 'Halx?lon' -- TRUE 'Hallon' SIMILAR TO 'H[a-c]?llon[x-z]?' -- TRUE
Звёздочка (*) сразу после символа или класса указывает на то, что для соответствия предыдущий элемент должен встретиться 0 или более раз:
'Icaque' SIMILAR TO 'Ica*que' -- TRUE 'Icaque' SIMILAR TO 'Icar*que' -- TRUE 'Icaque' SIMILAR TO 'I[a-c]*que' -- TRUE 'Icaque' SIMILAR TO '_*' -- TRUE 'Icaque' SIMILAR TO '[[:ALPHA:]]*' -- TRUE 'Icaque' SIMILAR TO 'Ica[xyz]*e' -- FALSE
Знак плюс (+) сразу после символа или класса указывает на то, что для соответствия предыдущий элемент должен встретиться 1 или более раз:
'Jujube' SIMILAR TO 'Ju_+' -- TRUE 'Jujube' SIMILAR TO 'Ju+jube' -- TRUE 'Jujube' SIMILAR TO 'Jujuber+' -- FALSE 'Jujube' SIMILAR TO 'J[jux]+be' -- TRUE 'Jujube' SIMILAR TO 'J[[:DIGIT:]]+ujube' -- FALSE
Если символ или класс сопровождаются числом, заключённым в фигурные скобки, то для соответствия необходимо повторение элемента точно это число раз:
'Kiwi' SIMILAR TO 'Ki{2}wi' -- FALSE 'Kiwi' SIMILAR TO 'K[ipw]{2}i' -- TRUE 'Kiwi' SIMILAR TO 'K[ipw]{2}' -- FALSE 'Kiwi' SIMILAR TO 'K[ipw]{3}' -- TRUE
Если число сопровождается запятой, то для соответствия необходимо повторение элемента как минимум это число раз:
'Limone' SIMILAR TO 'Li{2,}mone' –- FALSE 'Limone' SIMILAR TO 'Li{1,}mone' -- TRUE 'Limone' SIMILAR TOto 'Li[nezom]{2,}' -- TRUE
Если фигурные скобки содержат два числа (m
и n
), разделённые запятой, и второе число
больше первого, то для соответствия элемент должен быть повторен, как
минимум, m
раз и не больше
n
раз:
'Mandarijn' SIMILAR TO 'M[a-p]{2,5}rijn' -- TRUE 'Mandarijn' SIMILAR TO 'M[a-p]{2,3}rijn' -- FALSE 'Mandarijn' SIMILAR TO 'M[a-p]{2,3}arijn' -- TRUE
Кванторы ?, * и + сокращение для {0,1}, {0,} и {1,}, соответственно.
В условиях регулярных выражений можно использовать оператор ИЛИ (|). Соответствие произошло, если строка параметра соответствует, по крайней мере, одному из условий:
'Nektarin' SIMILAR TO 'Nek|tarin' -- FALSE 'Nektarin' SIMILAR TO 'Nektarin|Persika' -- TRUE 'Nektarin' SIMILAR TO 'M_+|N_+|P_+' – TRUE
Одна или более частей регулярного выражения могут быть сгруппированы в подвыражения (также называемые подмасками). Для этого их нужно заключить в круглые скобки:
'Orange' SIMILAR TO 'O(ra|ri|ro)nge' -- TRUE 'Orange' SIMILAR TO 'O(r[a-e])+nge' -- TRUE 'Orange' SIMILAR TO 'O(ra){2,4}nge' -- FALSE 'Orange' SIMILAR TO 'O(r(an|in)g|rong)?e' – TRUE
Для исключения из процесса сопоставления специальных символов (которые часто встречаются в регулярных выражениях) их надо экранировать. Специальных символов экранирования по умолчанию нет — их при необходимости определяет пользователь:
'Peer (Poire)' SIMILAR TO 'P[^ ]+ \(P[^ ]+\)' ESCAPE '\' -- TRUE 'Pera [Pear]' SIMILAR TO 'P[^ ]+ #[P[^ ]+#]' ESCAPE '#' -- TRUE 'Paron-Appledryck' SIMILAR TO 'P%$-A%' ESCAPE '$' -- TRUE 'Parondryck' SIMILAR TO 'P%--A%' ESCAPE '-' -- FALSE
Доступно в: DSQL, PSQL.
Синтаксис:
op1
IS [NOT] DISTINCT FROMop2
Два операнда считают различными (DISTINCT), если они имеют различные значения, или если одно из них — NULL, и другое нет. Они считаются NOT DISTINCT (равными), если имеют одинаковые значения или оба имеют значение NULL.
IS [NOT] DISTINCT FROM всегда возвращает TRUE или FALSE и никогда UNKNOWN (NULL) (неизвестное значение). Операторы «=» и «<>», наоборот, вернут UNKNOWN (NULL), если один или оба операнда имеют значение NULL.
Таблица 3.8. Результаты выполнения различных операторов сравнения
Характеристики операнда | Результаты различных операторов | |||
---|---|---|---|---|
= | IS NOT DISTINCT FROM | <> | IS DISTINCT FROM | |
Одинаковые значения | TRUE | TRUE | FALSE | FALSE |
Различные значения | FALSE | FALSE | TRUE | TRUE |
Оба NULL | UNKNOWN | TRUE | UNKNOWN | FALSE |
Одно NULL | UNKNOWN | FALSE | UNKNOWN | TRUE |
Примеры:
SELECT ID, NAME, TEACHER
FROM COURSES
WHERE START_DAY IS NOT DISTINCT FROM END_DAY
IF (NEW.JOB IS DISTINCT FROM OLD.JOB)
THEN POST_EVENT 'JOB_CHANGED';
См. также: IS NULL.
Доступно в: DSQL, PSQL, ESQL.
Синтаксис:
<value>
IS [NOT] NULL
Поскольку NULL не является значением, эти операторы не являются операторами сравнения. Предикат IS [NOT] NULL проверяет утверждение, что выражение в левой части имеет значение (IS NOT NULL) или не имеет значения (IS NULL).
Пример 3.3. Предикат IS NULL
Поиск записей о продажах, для которых не установлена дата отгрузки:
SELECT * FROM SALES WHERE SHIP_DATE IS NULL;
В эту группу предикатов включены предикаты, которые используют подзапросы и передают значения для всех видов утверждений в условиях поиска. Предикаты существования называются так потому, что они различными способами проверяют существование или отсутствие результатов подзапросов.
Доступно в: DSQL, PSQL, ESQL.
Синтаксис:
[NOT] EXISTS (<select_stmt>
)
Предикат EXISTS использует подзапрос в качестве аргумента. Если результат подзапроса будет содержать хотя бы одну запись, то предикат оценивается как истинный (TRUE), в противном случае предикат оценивается как ложный (FALSE).
Результат подзапроса может содержать несколько столбцов, поскольку значения не проверяются, а просто фиксируется факт наличия строк результата. Данный предикат может принимать только два значения: истина (TRUE) и ложь (FALSE).
Предикат NOT EXISTS возвращает FALSE, если результат подзапроса будет содержать хотя бы одну запись, в противном случае предикат вернёт TRUE.
Примеры:
Пример 3.4. Предикат EXISTS
Найти тех сотрудников, у которых есть проекты.
SELECT * FROM employee WHERE EXISTS (SELECT * FROM employee_project ep WHERE ep.emp_no = employee.emp_no)
Пример 3.5. Предикат NOT EXISTS
Найти тех сотрудников, у которых нет проектов.
SELECT * FROM employee WHERE NOT EXISTS (SELECT * FROM employee_project ep WHERE ep.emp_no = employee.emp_no)
Доступно в: DSQL, PSQL, ESQL.
Синтаксис:
<value>
[NOT] IN (<select_stmt>
|<value_list>
)<value_list>
::=<value_1>
[,<value_2>
...]
Предикат IN проверяет, присутствует ли значение выражения слева в указанном справа наборе значений. Набор значений не может превышать 1500 элементов. Предикат IN может быть переписан в следующей эквивалентной форме:
(<value>
=<value_1>
[OR<value>
=<value_2>
...])
При использовании предиката IN в поисковых условиях DML запросов, оптимизатор Firebird может использовать индекс по искомому столбцу, если он определён.
Во второй форме предикат IN проверяет, присутствует (или отсутствует, при использовании NOT IN) ли значение выражения слева в результате выполнения подзапроса справа. Результат подзапроса может содержать только один столбец, иначе будет выдана ошибка «count of column list and variable list do not match».
Запросы с использованием предиката IN с подзапросом, можно переписать на аналогичный запрос с использованием предиката EXISTS. Например, следующий запрос:
SELECT
model, speed, hd
FROM PC
WHERE
model IN (SELECT model
FROM product
WHERE maker = 'A');
Можно переписать на аналогичный запрос с использованием предиката EXISTS:
SELECT
model, speed, hd
FROM PC
WHERE
EXISTS (SELECT *
FROM product
WHERE maker = 'A'
AND product.model = PC.model);
Однако, запрос с использованием NOT IN не всегда даст тот же результат, что запрос NOT EXISTS. Причина заключается в том, что предикат EXISTS всегда возвращает TRUE или FALSE, тогда как предикат IN может вернуть NULL в следующих случаях:
Когда проверяемое значение равно NULL и список в IN не пуст.
Когда проверяемое значение не имеет совпадений в списке IN и одно из значений является NULL.
В этих двух случаях предикат IN вернёт NULL, в то время как соответствующий предикат EXISTS вернёт FALSE. В поисковых условиях или операторе IF оба результата обозначают «провал» и обрабатываются одинаково.
Однако на тех же данных NOT IN вернёт NULL, в то время как EXISTS вернёт TRUE, что приведёт к противоположному результату.
Это можно продемонстрировать следующим примером.
Предположим у вас есть такой запрос:
-- Ищем людей, которые не родились в тот же день, что -- известные жители Нью-Йорка SELECT P1.name AS NAME FROM Personnel P1 WHERE P1.birthday NOT IN (SELECT C1.birthday FROM Celebrities C1 WHERE С1.birthcity = 'New York');
Можно предположить, что аналогичный результат даст запрос с использованием предиката NOT EXISTS:
-- Ищем людей, которые не родились в тот же день, что -- известные жители Нью-Йорка SELECT P1.name AS NAME FROM Personnel P1 WHERE NOT EXISTS (SELECT * FROM Celebrities C1 WHERE C1.birthcity = 'New York' AND C1.birthday = P1.birthday);
Допустим, что в Нью-Йорке всего один известный житель, и его дата рождения неизвестна. При использовании предиката EXISTS подзапрос внутри него не выдаст результатов, так как при сравнении дат рождения с NULL результатом будет UNKNOWN. Это приведёт к тому, что результат предиката NOT EXISTS будет истинен для каждой строки основного запроса. В то время как результатом предиката NOT IN будет UNKNOWN и ни одна строка не будет выведена.
Примеры:
Пример 3.6. Предикат IN
Найти сотрудников с именами «Pete», «Ann» и «Roger»:
SELECT * FROM EMPLOYEE WHERE FIRST_NAME IN ('Pete', 'Ann', 'Roger');
Пример 3.7. Поисковый предикат IN
Найти все компьютеры, для которых существуют модели, производитель которых начинается на букву «A»:
SELECT
model, speed, hd
FROM PC
WHERE
model IN (SELECT model
FROM product
WHERE maker STARTING WITH 'A');
См. также: EXISTS.
Доступно в: DSQL, PSQL, ESQL.
Синтаксис:
[NOT] SINGULAR (<select_stmt>
)
Предикат SINGULAR использует подзапрос в качестве аргумента и оценивает его как истинный, если подзапрос возвращает одну и только одну строку результата, в противном случае предикат оценивается как ложный. Результат подзапроса может содержать несколько столбцов, поскольку значения не проверяются. Данный предикат может принимать только два значения: истина (TRUE) и ложь (FALSE).
Пример 3.8. Предикат SINGULAR
Найти тех сотрудников, у которых есть только один проект.
SELECT * FROM employee WHERE SINGULAR (SELECT * FROM employee_project ep WHERE ep.emp_no = employee.emp_no)
Квантором называется логический оператор, задающий количество объектов, для
которых данное утверждение истинно. Это логическое количество, а не числовое; оно
связывает утверждение с полным множеством возможных объектов. Такие предикаты
основаны на формальных логических квантификаторах общности и существования, которые
в формальной логике записываются как
В выражениях подзапросов количественные предикаты позволяют сравнивать отдельные значения с результатами подзапросов; их общая форма:
<value expression>
<comp op>
<quantifier>
<subquery>
Доступно в: DSQL, PSQL.
Синтаксис:
<value>
<op>
ALL (<select_stmt>
)
При использовании квантора ALL, предикат является истинным, если каждое значение выбранное подзапросом удовлетворяет условию в предикате внешнего запроса. Если подзапрос не возвращает ни одной строки, то предикат автоматически считается верным.
Пример 3.9. Квантор ALL
Вывести только тех заказчиков, чьи оценки выше, чем у каждого заказчика в Париже.
SELECT *
FROM Customers
WHERE rating > ALL
(SELECT rating
FROM Customers
WHERE city = 'Paris')
Если подзапрос возвращает пустое множество, то предикат будет истинен для каждого левостороннего значения, независимо от оператора. Это может показаться странным и противоречивым, потому что в этом случае каждое левостороннее значение рассматривается как одновременно больше, меньше, равное и неравное любому значению из правого потока.
Тем не менее, это нормально согласуется с формальной логикой: если множество пусто, то предикат верен 0 раз, т.е. для каждой строки в множестве.
Доступно в: DSQL, PSQL.
Синтаксис:
<value>
<op>
{ANY | SOME} (<select_stmt>
)
Эти два квантора идентичны по поведению. Очевидно, оба представлены в стандарте SQL для взаимозаменяемого использования с целью улучшения читаемости операторов. При использовании квантора ANY или SOME, предикат является истинным, если любое из значений выбранное подзапросом удовлетворяет условию в предикате внешнего запроса. Если подзапрос не возвращает ни одной строки, то предикат автоматически считается ложным.
Пример 3.10. Квантор ANY
Вывести только тех заказчиков, чьи оценки выше, чем у любого заказчика в Риме.
SELECT *
FROM Customers
WHERE rating > ANY
(SELECT rating
FROM Customers
WHERE city = 'Rome')
Data Definition Language (DDL) — язык описания данных. С помощью этого подмножества языка создаются, модифицируются и удаляются объекты базы данных (т.е. Метаданные).
В данном разделе описываются вопросы создания базы данных, подключения к существующей базе данных, изменения структуры файлов, перевод базы данных в состояние, необходимое для безопасного резервного копирования, и обратно и удаления базы данных.
Назначение: Создание новой базы данных.
Доступно в: DSQL, ESQL.
Синтаксис:
CREATE {DATABASE | SCHEMA} '<filespec>
' [USER 'username
' [PASSWORD 'password
'] [PAGE_SIZE [=]size
] [LENGTH [=]num
[PAGE[S]] [SET NAMES 'charset
'] [DEFAULT CHARACTER SETdefault_charset
[COLLATIONcollation
]] [<sec_file>
[<sec_file>
...]] [DIFFERENCE FILE 'diff_file
'];<filespec>
::= [<server_spec>
]{filepath
|db_alias
}<server_spec>
::=servername
[/{port
|service
}]: | \\servername
\<sec_file>
::= FILE 'filepath
' [LENGTH [=]num
[PAGE[S]] [STARTING [AT [PAGE]]pagenum
]
Таблица 4.1. Параметры оператора CREATE DATABASE
Параметр | Описание |
---|---|
filespec |
Спецификация первичного файла базы данных. |
server_spec |
Спецификация удалённого сервера. Включает в себя имя сервера и протокол. Необходима, если база данных создаётся на удалённом сервере. |
filepath |
Полный путь и имя файла, включая расширение. Имя файла должно быть задано в соответствии со спецификой используемой платформы. |
db_alias |
Псевдоним (alias) базы данных, присутствующий в файле
|
servername |
Имя сервера или IP адрес, на котором создаётся база данных. |
username |
Имя пользователя-владельца базы данных. Не чувствительно к регистру. |
password |
Пароль пользователя-владельца базы данных. Может содержать до 31 символа, но только первые 8 имеют значение. Чувствительно к регистру. |
size |
Размер страницы для базы данных. Допустимые значения 4096 (по умолчанию), 8192, 16384. |
num |
Максимальный размер первичного или вторичного файла в страницах. |
charset |
Задаёт набор символов подключения, доступного после успешного создания базы данных. |
default_charset |
Задаёт набор символов по умолчанию для строковых типов данных. |
collation |
Сортировка для набора символов по умолчанию. |
sec_file |
Спецификация вторичного файла. |
pagenum |
Номер страницы, с которой начинается вторичный файл базы данных. |
diff_file |
Путь и имя дельта файла. |
Оператор CREATE DATABASE
создаёт новую базу данных. Вы можете использовать
CREATE DATABASE
или CREATE SCHEMA
. Это синонимы.
База данных может состоять из одного или нескольких файлов. Первый, основной, файл называется первичным, остальные файлы — вторичными.
В настоящее время многофайловые базы данных являются атавизмом. Многофайловые базы данных имеет смысл использовать на старых файловых системах, в которых существует ограничение на размер любого файла. Например, в FAT32 нельзя создать файл больше 4х гигабайт.
Спецификация первичного файла — имя файла базы данных и его расширение с указанием к нему полного пути в соответствии с правилами используемой операционной системы. При создании базы данных файл базы данных должен отсутствовать. В противном случае будет выдано сообщение об ошибке и база данных не будет создана. Если полный путь к базе данных не указан, то база данных будет создана в одном из системных каталогов. В каком именно зависит от операционной системы.
Вместо полного пути к первичному файлу базы можно использовать псевдонимы (aliases).
Псевдонимы описываются в файле aliases.conf
в формате:
alias
=filepath
При создании базы данных на удалённом сервере необходимо указать спецификацию удалённого сервера. Спецификация удалённого сервера зависит от используемого протокола. Если вы при создании базы данных используете протокол TCP/IP, то спецификация первичного файла должна выглядеть следующим образом:
servername
:{filepath
|db_alias
}
Если вы при создании базы данных используете протокол под названием именованные каналы (Name Pipes), то спецификация первичного файла должна выглядеть следующим образом.
\\servername
\{filepath
|db_alias
}
Необязательные предложения USER
и PASSWORD
задают,
соответственно, имя и пароль пользователя присутствующего в базе данных безопасности
(security2.fdb
). Пользователя и пароль можно не указывать, если
установлены переменные окружения ISC_USER и ISC_PASSWORD. Создать базу данных может любой
авторизованный пользователь. Пользователь, указанный при создании базы данных, будет её
владельцем.
Необязательное предложение PAGE_SIZE
задаёт размер страницы базы данных.
Этот размер будет установлен для первичного файла и всех вторичных файлов базы данных. При
вводе размера страницы БД меньшего, чем 4096, он будет автоматически изменён на 4096.
Другие числа (не равные 4096, 8192 или 16384) будут изменены на ближайшее меньшее из
поддерживаемых значений. Если размер страницы базы данных не указан, то по умолчанию
принимается значение 4096.
Необязательное предложение LENGTH
задаёт максимальный размер первичного
или вторичного файла базы данных в страницах. При создании базы данных её первичный или
вторичный файл будут занимать минимально необходимое количество страниц для хранения
системных данных, не зависимо от величины, установленной в предложении
LENGHT
. Для единственного или последнего (в многофайловой базе данных) файла
значение LENGTH
никак не влияет на его размер. Файл будет автоматически
увеличивать свой размер по мере необходимости.
Необязательное предложение SET NAMES
задаёт набор символов подключения,
доступного после успешного создания базы данных. По умолчанию используется набор символов
NONE.
Необязательное предложение DEFAULT CHARACTER SET
задаёт набор символов по
умолчанию для строковых типов данных. Наборы символов применяются для типов CHAR, VARCHAR
и BLOB. По умолчанию используется набор символов NONE. Для набора символов по умолчанию
можно также указать сортировку по умолчанию (COLLATION). В этом случае сортировка станет
умалчиваемой для набора символов по умолчанию (т.е. для всей БД за исключением случаев
использования других наборов символов).
Предложение STARTING AT
задаёт номер страницы базы данных, с которой
должен начинаться следующий файл базы данных. Когда предыдущий файл будет полностью
заполнен данными в соответствии с заданным номером страницы, система начнёт помещать вновь
добавляемые данные в следующий файл базы данных.
Необязательное предложение DIFFERENCE FILE
задаёт путь и имя дельта
файла, в который будут записываться изменения, внесённые в БД после перевода её в режим
«безопасного копирования» («copy-safe») путём выполнения
команды ALTER DATABASE BEGIN BACKUP
. Полное описание данного параметра см. в
ALTER DATABASE.
Для того чтобы база данных была создана в нужном вам диалекте SQL, следует перед
выполнением оператора создания базы данных задать нужный диалект, выполнив оператор
SET SQL DIALECT
. По умолчанию база данных создаётся в 3 диалекте.
Пример 4.1. Создание базы данных в операционной системе Windows
Создание базы данных в операционной системе Windows расположенной на диске D с размером страницы 8192. Владельцем базы данных будет пользователь wizard. База данных будет в 1 диалекте, и использовать набор символов по умолчанию WIN1251.
SET SQL DIALECT 1; CREATE DATABASE 'D:\test.fdb' USER 'wizard' PASSWORD 'player' PAGE_SIZE = 8192 DEFAULT CHARACTER SET WIN1251;
Пример 4.2. Создание базы данных в операционной системе Linux
Создание базы данных в операционной системе Linux с размером страницы 4096. Владельцем базы данных будет пользователь wizard. База данных будет в 3 диалекте, и использовать набор символов по умолчанию UTF8 с умалчиваемой сортировкой UNICODE_CI_AI.
CREATE DATABASE '/home/firebird/test.fdb' USER 'wizard' PASSWORD 'player' DEFAULT CHARACTER SET UTF8 COLLATION UNICODE_CI_AI;
Пример 4.3. Создание базы данных на удалённом сервере
Создание базы данных на удалённом сервере baseserver расположенном по пути, на
который ссылается псевдоним test, описанный в файле aliases.conf
.
Используется протокол TCP. Владельцем базы данных будет пользователь wizard. База данных
будет в 3 диалекте, и использовать набор символов по умолчанию UTF8.
CREATE DATABASE 'baseserver:test' USER 'wizard' PASSWORD 'player' DEFAULT CHARACTER SET UTF8;
Пример 4.4. Создание многофайловой базы данных
Создание базы данных в 3 диалекте с набором символов по умолчанию UTF8. Первичный
файл будет содержать 10000 страниц с размером страницы 8192. Как только в процессе
работы с базой данных первичный файл будет заполнен, СУБД будет помещать новые данные во
вторичный файл test.fdb2
. Аналогичные действия будут происходить и
со вторым вторичным файлом. Размер последнего файла будет увеличиваться до тех пор, пока
это позволяет используемая операционная система или пока не будет исчерпана память на
внешнем носителе.
SET SQL DIALECT 3; CREATE DATABASE 'baseserver:D:\test.fdb' USER 'wizard' PASSWORD 'player' PAGE_SIZE = 8192 DEFAULT CHARACTER SET UTF8 FILE 'D:\test.fdb2' STARTING AT PAGE 10001 FILE 'D:\test.fdb3' STARTING AT PAGE 20001;
Пример 4.5. Создание многофайловой базы данных 2
Создание базы данных в 3 диалекте с набором символов по умолчанию UTF8. Первичный
файл будет содержать 10000 страниц с размером страницы 8192. Как только в процессе
работы с базой данных первичный файл будет заполнен, СУБД будет помещать новые данные во
вторичный файл test.fdb2
. Аналогичные действия будут происходить и
со вторым вторичным файлом.
SET SQL DIALECT 3; CREATE DATABASE 'baseserver:D:\test.fdb' USER 'wizard' PASSWORD 'player' PAGE_SIZE = 8192 LENGTH 10000 PAGES DEFAULT CHARACTER SET UTF8 FILE 'D:\test.fdb2' FILE 'D:\test.fdb3' STARTING AT PAGE 20001;
См. также: ALTER DATABASE, DROP DATABASE.
Назначение: Изменение структуры файлов базы данных или переключение её в состояние "безопасное для копирования".
Доступно в: DSQL, ESQL.
Синтаксис:
ALTER {DATABASE | SCHEMA} {<add_sec_clause>
[<add_sec_clausee>
...]} | {ADD DIFFERENCE FILE 'diff_file
' | DROP DIFFERENCE FILE} | {{BEGIN | END} BACKUP}<add_sec_clause>
::= ADD FILE<sec_file>
<sec_file>
::= 'filepath
' [STARTING [AT [PAGE]]pagenum
] [LENGTH [=]num
[PAGE[S]]