Руководство по языку 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]]
Таблица 4.2. Параметры оператора ALTER DATABASE
Параметр | Описание |
---|---|
add_sec_clause |
Инструкция для добавления вторичного файла базы данных. |
sec_file |
Спецификация вторичного файла. |
filepath |
Полный путь и имя дельта файла или вторичного файла базы данных. |
pagenum |
Номер страницы, с которой начинается вторичный файл базы данных. |
num |
Максимальный размер вторичного файла в страницах. |
diff_file |
Путь и имя дельта файла. |
Оператор ALTER DATABASE
изменяет структуру файлов базы данных или
переключает её в состояние «безопасное для копирования».
Только владелец базы данных и администраторы имеют привилегии на использование ALTER DATABASE.
Предложение ADD FILE
добавляет к базе данных вторичный файл. Для вторичного
файла необходимо указывать полный путь к файлу и имя вторичного файла. Описание вторичного
файла аналогично тому, что описано в операторе CREATE DATABASE.
Предложение ADD DIFFERENCE FILE
задаёт путь и имя дельта файла, в который
будут записываться изменения, внесённые в базу данных после перевода её в режим
«безопасного копирования» («copy-safe»). Этот оператор в
действительности не добавляет файла. Он просто переопределяет умалчиваемые имя и путь файла
дельты. Для изменения существующих установок необходимо сначала удалить ранее указанное
описание файла дельты с помощью оператора DROP DIFFERENCE FILE, а затем задать новое
описание файла дельты. Если не переопределять путь и имя файла дельты, то он будет иметь тот
же путь и имя, что и БД, но с расширением .delta
.
При задании относительного пути или только имени файла дельты он будет создаваться в текущем каталоге сервера. Для операционных систем Windows это системный каталог.
Предложение DROP DIFFERENCE FILE
удаляет описание (путь и имя) файла
дельты, заданное ранее командой ADD DIFFERENCE FILE
. На самом деле при
выполнении этого оператора файл не удаляется. Он удаляет путь и имя файла дельты и при
последующем переводе БД в режим «безопасного копирования» будут использованы
значения по умолчанию (т.е. тот же путь и имя что и у файла БД, но с расширением
.delta
).
Предложение BEGIN BACKUP
предназначено для перевода базы данных в режим
«безопасного копирования» («copy-safe»). Этот оператор
«замораживает» основной файл базы данных, что позволяет безопасно делать
резервную копию средствами файловой системы, даже если пользователи подключены и выполняют
операции с данными. При этом все изменения, вносимые пользователями в базу данных, будут
записаны в отдельный файл, так называемый дельта файл (delta
file).
Оператор BEGIN BACKUP
, не смотря на синтаксис, не начинает резервное
копирование базы данных, а лишь создаёт условия для его осуществления.
Предложение END BACKUP
предназначено для перевода базы данных из режима
«безопасного копирования» («copy-safe») в режим нормального
функционирования. Этот оператор объединяет файл дельты с основным файлом базы данных и
восстанавливает нормальное состояние работы, таким образом, закрывая возможность создания
безопасных резервных копий средствами файловой системы. (При этом безопасное резервное
копирование с помощью утилиты gbak остаётся доступным).
Пример 4.6. Добавление вторичного файла в базу данных
Как только в предыдущем первичном или вторичных файлах будет заполнено 30000
страниц, СУБД будет помещать данные во вторичный файл test4.fdb
.
ALTER DATABASE ADD FILE 'D:\test.fdb4' STARTING PAGE 30001;
Пример 4.10. Возвращение базы данных в режим нормального функционирования из режима «безопасного копирования»
ALTER DATABASE END BACKUP;
См. также: CREATE DATABASE, DROP DATABASE.
Назначение: Удаление базы данных к которой вы сейчас подключены.
Доступно в: DSQL, ESQL.
Синтаксис:
DROP DATABASE;
Оператор DROP DATABASE
удаляет текущую базу данных. Перед удалением базы
данных, к ней необходимо присоединиться. Оператор удаляет первичный, все вторичные файлы и
все файлы теневых копий.
Только владелец базы данных и администраторы имеют привилегии на использование DROP
DATABASE
.
См. также: CREATE DATABASE, ALTER DATABASE.
Теневая копия (shadow — дословно тень) является точной страничной копией базы данных. После создания теневой копии все изменения, сделанные в базе данных, сразу же отражаются и в теневой копии. Если по каким либо причинам первичный файл базы данных станет недоступным, то СУБД переключится на теневую копию.
В данном разделе рассматриваются вопросы создания и удаления теневых копий.
Это относится только к текущим операциям с базой данных, но не к новым подключениям. В случае поломки исходной базы данных администратор БД должен восстановить изначальные файлы базы данных, в том числе и с помощью файлов теневых копий. Только после этого будет возможно подключение новых клиентов.
Назначение: Создание теневой копии.
Доступно в: DSQL, ESQL.
Синтаксис:
CREATE SHADOWsh_num
[AUTO | MANUAL] [CONDITIONAL] 'filepath
' [LENGTH [=]num
[PAGE[S]]] [<secondary_file>
];<secondary_file>
::= FILE 'filepath
' LENGTH [=]num
[PAGE[S]] | STARTING [AT [PAGE]]pagenum
Таблица 4.3. Параметры оператора CREATE SHADOW
Параметр | Описание |
---|---|
sh_num |
Номер теневой копии — положительное число, идентифицирующее набор файлов теневой копии. |
filepath |
Имя файла и путь к нему в соответствии с требованиями ОС. |
num |
Максимальный размер теневой копии в страницах. |
secondary_file |
Спецификация вторичного файла. |
page_num |
Номер страницы, с которой должен начинаться вторичный файл копии. |
Оператор CREATE SHADOW создаёт новую теневую копию. Теневая копия начинает дублировать базу данных сразу в момент создания этой копии.
Теневые копии, как и база данных, могут состоять из нескольких файлов. Количество и размер файлов теневых копий не связано с количеством и размером файлов базы данных.
Для файлов теневой копии размер страницы устанавливается равным размеру страницы базы данных и не может быть изменён.
Если по каким либо причинам файл базы данных становится недоступным, то система преобразует тень в копию базы данных и переключается на неё. Теневая копия становится недоступной. Что будет дальше зависит от выбранного режима.
Когда теневая копия преобразуется в базу данных она становится недоступной. Теневая копия может также стать недоступной если будет удалён её файл, или закончится место на диске, где она расположена, или если этот диск повреждён.
Если выбран режим AUTO (значение по умолчанию), то в случае, когда теневая копия становится недоступной, автоматически прекращается использование этой копии и из базы данных удаляются все ссылки на нее. Работа с базой данных продолжается обычным образом без осуществления копирования в данную теневую копию.
Если указано ключевое слово CONDITIONAL, то система будет пытаться создать новую теневую копию. чтобы заменить потерянную. Это не всегда возможно, тогда вам потребуется создать новую тень вручную.
Если выбран режим MANUAL, то в случае, когда теневая копия становится недоступной, все попытки соединения с базой данных и обращения к ней будут вызывать сообщение об ошибке до тех пор, пока теневая копия не станет доступной или пока не будет удалена администратором БД с помощью оператора DROP SHADOW.
Необязательное предложение LENGTH задаёт максимальный размер первичного или вторичного файла теневой копии в страницах. Для единственного или последнего файла теневой копии значение LENGTH никак не влияет на его размер. Файл будет автоматически увеличивать свой размер по мере необходимости.
Предложение STARTING AT задаёт номер страницы теневой копии, с которой должен начинаться следующий файл теневой копии. Когда предыдущий файл будет полностью заполнен данными в соответствии с заданным номером страницы, система начнёт помещать вновь добавляемые данные в следующий файл теневой копии.
Только владелец базы данных и администраторы имеют привилегии на использование CREATE SHADOW.
Пример 4.13. Создание многофайловой теневой копии
CREATE SHADOW 2 'g:\data\test.sh1' LENGTH 8000 PAGES FILE 'g:\data\test.sh2';
См. также: CREATE DATABASE, ALTER DATABASE, DROP SHADOW.
Назначение: Удаление теневой копии.
Доступно в: DSQL, ESQL.
Синтаксис:
DROP SHADOW sh_num
;
Таблица 4.4. Параметры оператора DROP SHADOW
Параметр | Описание |
---|---|
sh_num |
Номер теневой копии — положительное число, идентифицирующее набор файлов теневой копии. |
Оператор DROP SHADOW удаляет указанную теневую копию из базы данных, с которой установлено текущее соединение. При удалении теневой копии удаляются все связанные с ней файлы, и прекращается процесс дублирования данных в эту теневой копии.
Только владелец базы данных и администраторы имеют привилегии на использование DROP SHADOW.
Домен (Domain) — один из объектов реляционной базы данных, при создании которого можно задать некоторые характеристики, а затем использовать ссылку на домен при определении столбцов таблиц, объявлении локальных переменных, входных и выходных аргументов в модулях PSQL.
В данном разделе рассматриваются синтаксис операторов создания, модификации и удаления доменов. Подробное описание доменов и их использования можно прочесть в главе Пользовательские типы данных — домены.
Назначение: Создание нового домена.
Доступно в: DSQL, ESQL.
Синтаксис:
CREATE DOMAINname
[AS]<datatype>
[DEFAULT {literal
| NULL |<context_var>
}] [NOT NULL] [CHECK (<dom_condition>
)] [COLLATEcollation_name
];<datatype>
::= {SMALLINT | INT[EGER] | BIGINT} [<array_dim>
] | {FLOAT | DOUBLE PRECISION} [<array_dim>
] | {DATE | TIME | TIMESTAMP} [<array_dim>
] | {DECIMAL | NUMERIC} [(precision
[,scale
])] [<array_dim>
] | {CHAR | CHARACTER | CHARACTER VARYING | VARCHAR} [(size
)] [<array_dim>
] [CHARACTER SETcharset_name
] | {NCHAR | NATIONAL CHARACTER | NATIONAL CHAR} [VARYING] [(size
)] [<array_dim>
] | BLOB [SUB_TYPE {subtype_num
|subtype_name
}] [SEGMENT SIZEseglen
] [CHARACTER SETcharset_name
] | BLOB [(seglen
[,subtype_num
])]<array_dim>
::= [[m
:]n
[,[m
:]n
...]]<dom_condition>
::= {<val>
<operator>
<val>
|<val>
[NOT] BETWEEN<val>
AND<val>
|<val>
[NOT] IN (<val>
[,<val>
...] |<select_list>
) |<val>
IS [NOT] NULL |<val>
IS [NOT] DISTINCT<val>
|<val>
[NOT] CONTAINING<val>
|<val>
[NOT] STARTING [WITH]<val>
|<val>
[NOT] LIKE<val>
[ESCAPE<val>
] |<val>
[NOT] SIMILAR TO<val>
[ESCAPE<val>
] |<val>
<operator>
{ALL | SOME | ANY} (<select_list>
) | [NOT] EXISTS (<select_expr>
) | [NOT] SINGULAR (<select_expr>
) | (<dom_condition>
) | NOT<dom_condition>
|<dom_condition>
OR<dom_condition>
|<dom_condition>
AND<dom_condition>
}<operator>
::= {= | < | > | <= | >= | !< | !> | <> | !=}<val>
::= { VALUE |literal
|<context_var>
|<expression>
| NULL | NEXT VALUE FORgenname
| GEN_ID(genname
,<val>
) | CAST(<val>
AS<datatype>
) | (<select_one>
) | func(<val>
[,<val>
...]) }
Таблица 4.5. Параметры оператора CREATE DOMAIN
Параметр | Описание |
---|---|
name |
Имя домена. Может содержать до 31 байта. |
datatype |
Тип данных SQL. |
literal |
Литерал. |
context_var |
Любая контекстная переменная, тип которой совместим с типом данных домена. |
dom_condition |
Условие домена. |
collation_name |
Имя порядка сортировки. Необходимо указывать если вы хотите чтобы порядок сортировки для домена отличался от порядка сортировки для набора символов по умолчанию этого домена. |
array_dim |
Размерность массива. |
m |
Начальный номер элемента в массиве, положительное целое число. |
n |
Последний номер элемента в массиве, положительное целое число. |
precision |
Точность. От 1 до 18. |
scale |
Масштаб. От 0 до 18, должно быть меньше или равно
|
size |
Максимальный размер строки в символах. |
charset_name |
Набор символов. |
subtype_num |
Номер подтипа BLOB. См. Подтипы BLOB. |
subtype_name |
Мнемоника подтипа BLOB. См. Подтипы BLOB. |
seglen |
Размер сегмента, не может превышать 65535. |
select_one |
Оператор SELECT выбирающий один столбец и возвращающий только одну строку. |
select_list |
Оператор SELECT выбирающий один столбец и возвращающий ноль и более строк. |
select_expr |
Оператор SELECT выбирающий несколько столбцов и возвращающий ноль и более строк. |
experssion |
Выражение. |
genname |
Имя последовательности (генератора). |
func |
Скалярная функция или UDF. |
Оператор CREATE DOMAIN создаёт новый домен.
В качестве типа домена можно использовать любой тип данных SQL. Для любого типа данных кроме BLOB можно указать размерность массива, если домен должен быть массивом. Размерность массива указывается в квадратных скобках. Чтобы не перепутать их с символами, означающими необязательные элементы, они выделены жирным шрифтом. При указании размерности массива указываются два числа через двоеточие. Первое число означает начальный номер элемента массива, второе – конечный. Если указано только одно число, то оно означает последний номер в элементе массива, а первым номером считается 1. Если у массива два и более измерения, то они перечисляются через запятую.
Для типов CHAR, VARCHAR и BLOB с подтипом TEXT можно указать набор символов в предложении CHARACTER SET. Если набор символов не указан, то по умолчанию принимается тот набор символов, который был указан при создании базы данных. Если же при создании базы данных не был указан набор символов, то при создании домена по умолчанию принимается набор символов NONE. В этом случае данные хранятся и извлекаются, так как они были поданы. В столбец, основанный на таком домене, можно загружать данные в любой кодировке, но невозможно загрузить эти данные в столбец с другой кодировкой. Транслитерация не выполняется между исходными и конечными кодировками, что может приводить к ошибкам.
Необязательное предложение DEFAULT позволяет указать значение по умолчанию для домена. Это значение будет помещено в столбец таблицы, который ссылает на данный домен, при выполнении оператора INSERT, если значение не будет указано для этого столбца. Локальные переменные и аргументы PSQL модулей, которые ссылаются на этот домен, будут инициализированы значением по умолчанию. В качестве значения по умолчанию может быть литерал совместимый по типу, неизвестное значение NULL и контекстная переменная, тип которой совместим с типом домена.
Предложение NOT NULL запрещает столбцам и переменным, основанным на домене, присваивать значение NULL.
Необязательное предложение CHECK задаёт ограничение домена. Ограничение домена задаёт условия, которому должны удовлетворять значения столбцов таблицы или переменных, которые ссылаются на данный домен. Условие должно быть помещено в круглые скобки. Условие – это логическое выражение, называемое также предикат, которое может возвращать значения TRUE (истина), FALSE (ложь) и UNKNOWN (неизвестно). Условие считается выполненным, если предикат возвращает значение TRUE или UNKNOWN (эквивалент NULL). Если предикат возвращает FALSE, то значение не будет принято.
Ключевое слово VALUE в ограничении домена является заменителем столбца таблицы, который основан на данном домене, или переменной PSQL модуля. Оно содержит значение, присваиваемое переменной или столбцу таблицы. Ключевое слово VALUE может быть использовано в любом месте ограничения CHECK, но обычно его используют в левой части условия.
Необязательное предложение COLLATE позволяет задать порядок сортировки, если домен основан на одном из строковых типов данных (за исключением BLOB). Если порядок сортировки не указан, то по умолчанию принимается порядок сортировки умалчиваемый для указанного набора сортировки при создании домена.
Создать домен может любой пользователь, соединившийся с базой данных.
Пример 4.15. Создание домена, который может принимать значения больше 1000.
CREATE DOMAIN CUSTNO AS INTEGER DEFAULT 10000 CHECK (VALUE > 1000);
Пример 4.16. Создание домена, который может принимать значения 'Да' и 'Нет'.
CREATE DOMAIN D_BOOLEAN AS CHAR(3) CHECK (VALUE IN ('Да', 'Нет'));
Пример 4.17. Создание домена с набором символов UTF8 и порядком сортировки UNICODE_CI_AI.
CREATE DOMAIN FIRSTNAME AS
VARCHAR(30) CHARACTER SET UTF8
COLLATE UNICODE_CI_AI;
Пример 4.18. Создание домена со значением по умолчанию.
CREATE DOMAIN D_DATE AS DATE DEFAULT CURRENT_DATE NOT NULL;
Пример 4.19. Создание домена, определённого как массив из 2 элементов.
Создание домена, определённого как массив из 2 элементов типа NUMERIC(18, 3), нумерация элементов начинается с 1.
CREATE DOMAIN D_POINT AS NUMERIC(18, 3) [2];
Вы можете использовать домены определённые как массив только для определения столбцов таблиц. Вы не можете использовать такие домены для определения локальных переменных и аргументов PSQL модулей.
См. также: ALTER DOMAIN, DROP DOMAIN.
Назначение: Изменение текущих характеристик домена или его переименование.
Доступно в: DSQL, ESQL.
Синтаксис:
ALTER DOMAINname
[{TOnew_name
}] [{SET DEFAULT {literal
| NULL |<context_var>
} | DROP DEFAULT}] [{ADD [CONSTRAINT] CHECK (<dom_condition>
) | DROP CONSTRAINT}] [{TYPE<datatype>
}];<datatype>
::= {SMALLINT | INT[EGER] | BIGINT} [<array_dim>
] | {FLOAT | DOUBLE PRECISION} [<array_dim>
] | {DATE | TIME | TIMESTAMP} [<array_dim>
] | {DECIMAL | NUMERIC} [(precision
[,scale
])] [<array_dim>
] | {CHAR | CHARACTER | CHARACTER VARYING | VARCHAR} [(size
)] [<array_dim>
] [CHARACTER SETcharset_name
] | {NCHAR | NATIONAL CHARACTER | NATIONAL CHAR} [VARYING] [(size
)] [<array_dim>
] | BLOB [SUB_TYPE {subtype_num
|subtype_name
}] [SEGMENT SIZEseglen
] [CHARACTER SETcharset_name
] | BLOB [(seglen
[,subtype_num
])]<array_dim>
::= [[m
:]n
[,[m
:]n
...]]<dom_condition>
::= {<val>
<operator>
<val>
|<val>
[NOT] BETWEEN<val>
AND<val>
|<val>
[NOT] IN (<val>
[,<val>
...] |<select_list>
) |<val>
IS [NOT] NULL |<val>
IS [NOT] DISTINCT<val>
|<val>
[NOT] CONTAINING<val>
|<val>
[NOT] STARTING [WITH]<val>
|<val>
[NOT] LIKE<val>
[ESCAPE<val>
] |<val>
[NOT] SIMILAR TO<val>
[ESCAPE<val>
] |<val>
<operator>
{ALL | SOME | ANY} (<select_list>
) | [NOT] EXISTS (<select_expr>
) | [NOT] SINGULAR (<select_expr>
) | (<dom_condition>
) | NOT<dom_condition>
|<dom_condition>
OR<dom_condition>
|<dom_condition>
AND<dom_condition>
}<operator>
::= {= | < | > | <= | >= | !< | !> | <> | !=}<val>
::= { VALUE |literal
|<context_var>
|<expression>
| NULL | NEXT VALUE FORgenname
| GEN_ID(genname
,<val>
) | CAST(<val>
AS<datatype>
) | (<select_one>
) | func(<val>
[,<val>
...]) }
Таблица 4.6. Параметры оператора ALTER DOMAIN
Параметр | Описание |
---|---|
name |
Имя домена. |
new_name |
Новое имя домена. Может содержать до 31 байта. |
datatype |
Тип данных SQL. |
literal |
Литерал. |
context_var |
Любая контекстная переменная, тип которой совместим с типом данных домена. |
dom_condition |
Условие домена. |
collation_name |
Имя порядка сортировки. Необходимо указывать если вы хотите чтобы порядок сортировки для домена отличался от порядка сортировки для набора символов по умолчанию этого домена. |
array_dim |
Размерность массива. |
m |
Начальный номер элемента в массиве, положительное целое число. |
n |
Последний номер элемента в массиве, положительное целое число. |
precision |
Точность. От 1 до 18. |
scale |
Масштаб. От 0 до 18, должно быть меньше или равно
|
size |
Максимальный размер строки в символах. |
charset_name |
Имя набора символов. Необходимо указывать, если вы хотите чтобы набор символов домена отличался от набора символов по умолчанию для базы данных. |
subtype_num |
Номер подтипа BLOB. См. Подтипы BLOB. |
subtype_name |
Мнемоника подтипа BLOB. См. Подтипы BLOB. |
seglen |
Размер сегмента, не может превышать 65535. |
val |
Значение. |
select_one |
Оператор SELECT выбирающий один столбец и возвращающий только одну строку. |
select_list |
Оператор SELECT выбирающий один столбец и возвращающий ноль и более строк. |
select_expr |
Оператор SELECT выбирающий несколько столбцов и возвращающий ноль и более строк. |
experssion |
Выражение. |
genname |
Имя последовательности (генератора). |
func |
Скалярная функция. |
Оператор ALTER DOMAIN изменяет текущие характеристики домена, в том числе и его имя. В одном операторе ALTER DOMAIN можно выполнить любое количество изменений домена.
Предложение TO позволяет переименовать домен. Имя домена можно изменить, если не существует зависимостей от этого домена, т.е. столбцов таблиц, локальных переменных и аргументов процедур, ссылающихся на данный домен.
Предложение SET DEFAULT позволяет установить новое значение по умолчанию. Если домен уже содержал значение по умолчанию, то установка нового значения по умолчанию не требует предварительного удаления старого.
Предложение DROP DEFAULT удаляет ранее установленное для домена значение по умолчанию. В этом случае значением по умолчанию становится значение NULL.
Предложение ADD [CONSTRAINT] CHECK добавляет условие ограничения домена. Если домен уже содержал ограничение CHECK, то его предварительно необходимо удалить с помощью предложения DROP [CONSTRAINT] CHECK.
Предложение TYPE позволяет изменить тип домена на другой допустимый тип. Не допустимы любые изменения типа, которые могут привести к потере данных. Например, количество символов в новом типе для домена не может быть меньше, чем было установлено ранее.
При изменении описания домена, существующий PSQL код, может стать некорректным. Информация о том, как это обнаружить, находится в приложении Поле RDB$VALID_BLR.
Если домен был объявлен как массив, то изменить ни его тип, ни размерность нельзя. Также нет возможности изменить любой другой тип на тип массив.
В Firebird 2.5 и ниже не существует возможности установить и снять ограничение NOT NULL для домена.
Не существует способа изменить сортировку по умолчанию. В этом случае необходимо удалить домен и пересоздать его с новыми атрибутами.
Изменить описание домена может любой пользователь, подключенный к базе данных, при условии что это не мешает зависимым объектам.
Пример 4.22. Удаление значения по умолчанию и добавления ограничения для домена.
ALTER DOMAIN D_DATE
DROP DEFAULT
ADD CONSTRAINT CHECK (VALUE >= date '01.01.2000');
Пример 4.23. Изменение ограничения домена.
ALTER DOMAIN D_DATE DROP CONSTRAINT; ALTER DOMAIN D_DATE ADD CONSTRAINT CHECK (VALUE BETWEEN date '01.01.1900' AND date '31.12.2100');
См. также: CREATE DOMAIN, DROP DOMAIN.
Назначение: Удаление существующего домена.
Доступно в: DSQL, ESQL.
Синтаксис:
DROP DOMAIN domain_name
;
Оператор DROP DOMAIN удаляет домен, существующий в базе данных. Невозможно удалить домен, на который ссылаются столбцы таблиц базы данных или если он был задействован в одном из PSQL модулей. Чтобы удалить такой домен необходимо удалить из таблиц все столбцы, ссылающиеся на домен и удалить все ссылки на домен из PSQL модулей.
Удалить домен может любой пользователь, подключенный к базе данных, при условии что это не мешает зависимым объектам.
См. также: CREATE DOMAIN, ALTER DOMAIN.
Firebird — это реляционная СУБД. Данные в таких базах хранятся в таблицах. Таблица — это плоская двухмерная структура, содержащая произвольное количество строк (row). Строки таблицы часто называют записями (record). Все строки таблицы имеют одинаковую структуру и состоят из столбцов (column). Столбцы таблицы часто называют полями (fields). Таблица должна иметь хотя бы один столбец. С каждым столбцом связан определённый тип данных SQL.
В данном разделе рассматриваются вопросы создания, модификации и удаления таблиц базы данных.
Назначение: Создание новой таблицы.
Доступно в: DSQL, ESQL.
Синтаксис:
CREATE [GLOBAL TEMPORARY] TABLEtablename
[EXTERNAL [FILE] '<filespec>
'] (<col_def>
[, {<col_def>
|<tconstraint>
} ...]) [ON COMMIT {DELETE | PRESERVE} ROWS];<col_def>
::=<regular_col_def>
|<computed_col_def>
<regular_col_def>
::=colname
{<datatype>
|domainname
} [DEFAULT {literal
| NULL |<context_var>
}] [NOT NULL] [<col_constraint>
] [COLLATEcollation_name
]<computed_col_def>
::=colname
[<datatype>
] {COMPUTED [BY] | GENERATED ALWAYS AS} (<expression>
)<datatype>
::= { {SMALLINT | INT[EGER] | BIGINT} [<array_dim>
] | {FLOAT | DOUBLE PRECISION} [<array_dim>
] | {DATE | TIME | TIMESTAMP} [<array_dim>
] | {DECIMAL | NUMERIC} [(precision
[,scale
])] [<array_dim>
] | {CHAR | CHARACTER | CHARACTER VARYING | VARCHAR} [(size
)] [<array_dim>
] [CHARACTER SETcharset_name
] | {NCHAR | NATIONAL CHARACTER | NATIONAL CHAR} [VARYING] [(size
)] [<array_dim>
] | BLOB [SUB_TYPE {subtype_num
|subtype_name
}] [SEGMENT SIZEseglen
] [CHARACTER SETcharset_name
] | BLOB [(seglen
[,subtype_num
])] }<array_dim>
::= [[m
:]n
[,[m
:]n
...]]<col_constraint>
::= [CONSTRAINTconstr_name
] { UNIQUE [<using_index>
] | PRIMARY KEY [<using_index>
] | REFERENCES other_table [(other_col
)] [ON DELETE { NO ACTION | CASCADE | SET DEFAULT | SET NULL}] [ON UPDATE { NO ACTION | CASCADE | SET DEFAULT | SET NULL}] [<using_index>
] | CHECK (<check_condition>
) }<tconstraint>
::= [CONSTRAINTconstr_name
] { UNIQUE (<col_list>
) [<using_index>
] | PRIMARY KEY (<col_list>
) [<using_index>
] | FOREIGN KEY (<col_list>
) REFERENCESother_table
[(<col_list>
)] [ON DELETE { NO ACTION | CASCADE | SET DEFAULT | SET NULL}] [ON UPDATE { NO ACTION | CASCADE | SET DEFAULT | SET NULL}] [<using_index>
] | CHECK (<check_condition>
) }<col_list>
::=colname
[,colname
...]<using_index>
::= USING [ASC[ENDING] | DESC[ENDING]] INDEXindexname
<check_condition>
::= {<val>
<operator>
<val>
|<val>
[NOT] BETWEEN<val>
AND<val>
|<val>
[NOT] IN (<val>
[,<val>
...] |<select_list>
) |<val>
IS [NOT] NULL |<val>
IS [NOT] DISTINCT<val>
|<val>
[NOT] CONTAINING<val>
|<val>
[NOT] STARTING [WITH]<val>
|<val>
[NOT] LIKE<val>
[ESCAPE<val>
] |<val>
[NOT] SIMILAR TO<val>
[ESCAPE<val>
] |<val>
<operator>
{ALL | SOME | ANY} (<select_list>
) | [NOT] EXISTS (<select_expr>
) | [NOT] SINGULAR (<select_expr>
) | (<check_condition>
) | NOT<check_condition>
|<check_condition>
OR<check_condition>
|<check_condition>
AND<check_condition>
}<operator>
::= <> | != | ^= | ~= | = | < | > | <= | >= | !< | ^< | ~< | !> | ^> | ~><val>
::=colname
[[<array_idx>
[,<array_idx>
...]]] |literal
|<context_var>
|<expression>
| NULL | NEXT VALUE FORgenname
| GEN_ID(genname
,<val>
) | CAST(<val>
AS<datatype>
) | (<select_one>
) |func
(<val>
[,<val>
...])
Таблица 4.8. Параметры оператора CREATE TABLE
Параметр | Описание |
---|---|
tablename |
Имя таблицы, может содержать до 31 байта. |
filespec |
Спецификация файла (только для внешних таблиц). |
colname |
Имя столбца таблицы, может содержать до 31 байта. |
<datatype> |
Тип данных SQL. |
domain_name |
Имя домена. |
<col_constraint> |
Ограничение столбца. |
<tconstraint> |
Ограничение таблицы. |
constr_name |
Имя ограничения, может содержать до 31 байта. |
other_table |
Имя таблицы, на которую ссылается внешний ключ. |
other_col |
Столбец таблицы, на которую ссылается внешний ключ. |
<using_index> |
Позволяет задать имя автоматически создаваемого индекса для ограничения, и опционально определить, какой это будет индекс — по возрастанию (по умолчанию) или по убыванию. |
literal |
Литерал. |
context_var |
Любая контекстная переменная, тип которой совместим с типом данных столбца. |
<check_condition> |
Условие проверки ограничения. Выполняется, если оценивается как TRUE или NULL/UNKNOWN. |
collation_name |
Имя порядка сортировки. Необходимо указывать если вы хотите чтобы порядок сортировки для столбца отличался от порядка сортировки для набора символов по умолчанию этого столбца. |
<array_dim> |
Размерность массива. |
m |
Начальный номер элемента в массиве, положительное целое число. |
n |
Последний номер элемента в массиве, положительное целое число. |
precision |
Точность. От 1 до 18. |
scale |
Масштаб. От 0 до 18, должно быть меньше или равно
|
size |
Максимальный размер строки в символах. |
charset_name |
Имя набора символов. Необходимо указывать, если вы хотите чтобы набор символов столбца отличался от набора символов по умолчанию для базы данных. |
subtype_num |
Номер подтипа BLOB. См. Подтипы BLOB. |
subtype_name |
Мнемоника подтипа BLOB. См. Подтипы BLOB. |
seglen |
Размер сегмента, не может превышать 65535. |
<select_one> |
Оператор SELECT выбирающий один столбец и возвращающий только одну строку. |
<select_list> |
Оператор SELECT выбирающий один столбец и возвращающий ноль и более строк. |
<select_expr> |
Оператор SELECT выбирающий несколько столбцов и возвращающий ноль и более строк. |
<experssion> |
Выражение. |
genname |
Имя последовательности (генератора). |
func |
Скалярная функция или UDF. |
Создать новую таблицу может любой пользователь, подключённый к базе данных. Пользователь, создавший таблицу, становится её владельцем.
Оператор CREATE TABLE создаёт новую таблицу. Имя таблицы должно быть уникальным среди имён всех таблиц, представлений (VIEWs) и хранимых процедур базы данных.
Таблица может содержать, по меньшей мере, один столбец и произвольное количество ограничений таблицы.
Имя столбца должно быть уникальным для создаваемой таблицы. Для столбца обязательно должен быть указан либо тип данных, либо имя домена, характеристики которого будут скопированы для столбца, либо должно быть указано, что столбец является вычисляемым.
В качестве типа столбца можно использовать любой тип данных SQL.
Для типов CHAR, VARCHAR и BLOB с подтипом TEXT можно указать набор символов в предложении CHARACTER SET. Если набор символов не указан, то по умолчанию принимается тот набор символов, что был указан при создании базы данных. Если же при создании базы данных не был указан набор символов, то по умолчанию принимается набор символов NONE. В этом случае данные хранятся и извлекаются, так как они были поданы. В столбец можно загружать данные в любой кодировке, но невозможно загрузить эти данные в столбец с другой кодировкой. Транслитерация между исходными и конечными кодировками не выполняется, что может приводить к ошибкам.
Необязательное предложение COLLATE позволяет задать порядок сортировки для строковых типов данных (за исключением BLOB). Если порядок сортировки не указан, то по умолчанию принимается порядок сортировки по умолчанию для указанного набора сортировки.
По умолчанию столбец может принимать значение NULL.
Необязательное предложение NOT NULL указывает, что столбцу не может быть присвоено значение NULL.
Необязательное предложение DEFAULT позволяет указать значение по умолчанию для столбца таблицы. Это значение будет помещено в столбец таблицы при выполнении оператора INSERT, если значение не будет указано для этого столбца. В качестве значения по умолчанию может быть литерал совместимый по типу, неизвестное значение NULL или контекстная переменная, тип которой совместим с типом столбца. Если значение по умолчанию явно не устанавливается, то подразумевается пустое значение, NULL. Использование выражений в значении по умолчанию недопустимо.
Для определения столбца, можно воспользоваться ранее описанным доменом. Если определение столбца основано на домене, оно может включать новое значение по умолчанию, дополнительные ограничения CHECK, предложение COLLATE, которые перекрывают значения указанные при определении домена. Определение такого столбца может включать дополнительные ограничения столбца, например, NOT NULL, если домен его ещё не содержит.
Следует обратить внимание на то, что если в определении домена было указано NOT NULL, на уровне столбца невозможно определить допустимость использования в нем значения NULL. Если вы хотите чтобы на основе домена можно было определять столбцы допускающие псевдозначение NULL и не допускающее его, то хорошей практикой является создание домена допускающего NULL и указание ограничения NOT NULL у столбцов таблицы там где это необходимо.
Вычисляемые поля могут быть определены с помощью предложения COMPUTED [BY] или GENERATED ALWAYS AS (согласно стандарту SQL-2003). Они эквивалентны по смыслу. Для вычисляемых полей не требуется описывать тип данных (но допустимо), СУБД вычисляет подходящий тип в результате анализа выражения. В выражении требуется указать корректную операцию для типов данных столбцов, входящих в его состав. При явном указании типа столбца для вычисляемого поля результат вычисления приводится к указанному типу, то есть, например, результат числового выражения можно вывести как строку. Вычисление выражения происходит для каждой строки выбранных данных, если в операторе выборки данных SELECT, присутствует такой столбец.
Вместо использования вычисляемого столбца в ряде случаев имеет смысл использовать обычный столбец, значение которого рассчитывается в триггерах на добавление и обновление данных. Это может снизить производительность вставки/модификации записей, но повысит производительность выборки данных.
Для любого типа данных кроме BLOB можно указать размерность массива, если столбец должен быть массивом. Размерность массива указывается в квадратных скобках. Чтобы не перепутать их с символами, означающими необязательные элементы, они выделены жирным шрифтом. При указании размерности массива указываются два числа через двоеточие. Первое число означает начальный номер элемента массива, второе — конечный. Если указано только одно число, то оно означает последний номер в элементе массива, а первым номером считается 1. Для многомерного массива размерности массива перечисляются через запятую.
Существуют четыре вида ограничений:
первичный ключ (PRIMARY KEY);
уникальный ключ (UNIQUE);
внешний ключ (REFERENCES или FOREIGN KEY);
проверочное ограничение (CHECK).
Ограничения могут быть указаны на уровне столбца (ограничения столбцов) или на уровне таблицы (табличные ограничения). Ограничения уровня таблицы необходимы, когда ключи (ограничение уникальности, первичный ключ или внешний ключ) должны быть сформированы по нескольким столбцам, или, когда ограничение CHECK включает несколько столбцов, т.е. действует на уровне записи. Синтаксис для некоторых типов ограничений может незначительно отличаться в зависимости от того определяется ограничение на уровне столбца или на уровне таблицы.
Ограничение на уровне столбца указывается после определения других характеристик столбца. Оно может включать только столбец указанный в этом определении.
Ограничения на уровне таблицы указываются после определений всех столбцов. Ограничения таблицы являются более универсальным способом записи ограничений, поскольку позволяют ограничение более чем для одного столбца таблицы.
Вы можете смешивать ограничения столбцов и ограничения таблиц в одном операторе CREATE TABLE.
Если имя ограничения не задано, то ограничению будет присвоено имя, автоматически генерированное СУБД. Для любого ограничения вы можете указать имя.
Для первичного ключа (PRIMARY KEY), уникального ключа (UNIQUE) и внешнего ключа (REFERENCES) система автоматически создаёт соответствующий индекс. Если задано имя ограничения, то автоматически создаваемому индексу будет присвоено это имя (при отсутствии предложения USING).
Ограничение первичного ключа PRIMARY KEY строится на поле с заданным ограничением NOT NULL и требует уникальности значений столбца. Таблица может иметь только один первичный ключ.
Первичный ключ по единственному столбцу может быть определён как на уровне столбца, так и на уровне таблицы.
Первичный ключ по нескольким столбцам может быть определён только на уровне таблицы.
Ограничение уникального ключа UNIQUE задаёт для значений столбца требование уникальности содержимого. Таблица может содержать любое количество уникальных ключей.
Как и первичный ключ, ограничение уникальности может быть определено на нескольких столбцах. В этом случае вы должны определять его как ограничение уровня таблицы.
В отличие от первичного ключа, в таких полях допускаются значения NULL для любого количества строк. Таким образом, можно определить ограничение уникальности для столбцов не имеющих ограничения NOT NULL.
Для уникальных ключей, содержащих несколько столбцов, логика немного сложнее:
Во всех столбцах, входящих в уникальный ключ, нет ограничения NOT NULL;
Разрешено хранение значения NULL в столбцах, входящих в уникальный ключ, в нескольких строках;
Разрешены строки, имеющие в одном из столбцов уникального ключа значение NULL, а остальные столбцы заполнены значениями и эти значения различны хотя бы в одном из них;
Запрещены строки, имеющие в одном из столбцов уникального ключа значение NULL, а остальные столбцы заполнены значениями, и эти значения имеют совпадения хотя бы в одном из них.
Для уникальных ключей, содержащих несколько столбцов, допускаются дубликаты значений NULL только тогда, когда они помещаются во все столбцы ограничения. В остальных случаях значения NULL будут рассматриваться как одно из обычных значений (не UNKNOWN).
RECREATE TABLE t( x int, y int, z int, unique(x,y,z)); INSERT INTO t values( NULL, 1, 1 ); INSERT INTO t values( NULL, NULL, 1 ); INSERT INTO t values( NULL, NULL, NULL ); INSERT INTO t values( NULL, NULL, NULL ); -- Разрешено INSERT INTO t values( NULL, NULL, 1 ); -- Запрещено
На уровне столбца ограничение внешнего ключа определяется предложением REFERENCES. После ключевого слова REFERENCES указывается имя родительской таблицы, на первичный или уникальный ключ которой ссылается описываемый внешний ключ. Имя столбца родительской таблицы, являющегося первичным (уникальным) ключом, помещается сразу после имени таблицы и заключается в круглые скобки, например:
... , ARTIFACT_ID INTEGER REFERENCES COLLECTION (ARTIFACT_ID),
Синтаксис определения внешнего ключа на уровне таблицы несколько отличается. После определения всех столбцов, с их ограничениями уровня столбца, вы можете определить именованное ограничение внешнего ключа уровня таблицы, используя ключевые слова FOREIGN KEY и имён столбцов, для которых оно применяется:
... , CONSTRAINT FK_ARTSOURCE FOREIGN KEY(DEALER_ID, COUNTRY) REFERENCES DEALER (DEALER_ID, COUNTRY),
Внешний ключ не требует ограничения NOT NULL для столбца или столбцов на которые ссылается внешний ключ, хотя оно будет, если внешний ключ ссылается на столбец или столбцы входящие в первичный ключ родительской таблицы. Тем не менее, внешний ключ может ссылаться на столбец или столбцы, входящие в уникальный ключ. NULL допускается в уникальных ключах, и, с некоторыми ограничениями, в уникальных ключах построенных на нескольких столбцах (см. обсуждение выше).
Для обеспечения дополнительной целостности данных можно указать необязательные опции ON DELETE и ON UPDATE, которые обеспечат согласованность данных между родительскими и дочерними таблицами по заданным правилам:
Для обеспечения ссылочной целостности внешнего ключа, когда изменяется или удаляется значение связанного первичного или уникального ключа, могут быть выполнены следующие действия:
NO ACTION — не будет выполнено никаких действий; в клиентской программе должны быть предприняты специальные меры по поддержанию ссылочной целостности данных, иначе обновление/удаление не будет произведено и будет выдано соответствующее сообщение об ошибке;
CASCADE — при изменении или удалении значения первичного ключа над значением внешнего ключа будут произведены те же действия. При выполнении удаления строки в главной таблице в подчинённой таблице должны быть удалены все записи, имеющие те же значения внешнего ключа, что и значение первичного (уникального) ключа удалённой строки главной таблицы. При выполнении обновления записи главной таблицы в подчинённой таблице должны быть изменены все значения внешнего ключа, имеющие те же значения, что и значение первичного (уникального) ключа изменяемой строки главной таблицы;
SET DEFAULT — значения внешнего ключа всех соответствующих строк в подчинённой таблице устанавливаются в значение по умолчанию, заданное в предложении DEFAULT для этого столбца;
SET NULL — значения внешнего ключа всех соответствующих строк в подчинённой таблице устанавливаются в пустое значение NULL.
Ограничение CHECK задаёт условие, которому должны удовлетворять значения, помещаемые в данный столбец. Условие — это логическое выражение, называемое также предикат, которое может возвращать значения TRUE (истина), FALSE (ложь) и UNKNOWN (неизвестно). Условие считается выполненным, если предикат возвращает значение TRUE или UNKNOWN (эквивалент NULL). Если предикат возвращает FALSE, то значение не будет принято. Это условие используется при добавлении в таблицу новой строки (оператор INSERT) и при изменении существующего значения столбца таблицы (оператор UPDATE), а также операторов, в которых может произойти одно из этих действий (UPDATE OR INSERT, MERGE).
При использовании предложения CHECK для столбца, базирующегося на домене, следует помнить, что выражение в CHECK лишь дополняет условие проверки, которое может уже быть определено в домене.
На уровне столбца или таблицы выражение в предложении CHECK ссылается на входящее значения с помощью с помощью идентификаторов столбцов, в отличие от доменов, где в ограничении CHECK для этих целей используется ключевое слово VALUE.
Примеры:
Пример 4.26. CHECK ограничения уровня столбца и уровня таблицы
CREATE TABLE PLACES ( ... LAT DECIMAL(9, 6) CHECK (ABS(LAT) <= 90), LON DECIMAL(9, 6) CHECK (ABS(LON) <= 180), ... CONSTRAINT CHK_POLES CHECK (ABS(LAT) < 90 OR LON = 0) );
Пример 4.27. Создание таблицы
CREATE TABLE COUNTRY (
COUNTRY COUNTRYNAME NOT NULL PRIMARY KEY,
CURRENCY VARCHAR(10) NOT NULL);
Пример 4.28. Создание таблицы с заданием именованного первичного и уникального ключей
CREATE TABLE STOCK (
MODEL SMALLINT NOT NULL CONSTRAINT PK_STOCK PRIMARY KEY,
MODELNAME CHAR(10) NOT NULL,
ITEMID INTEGER NOT NULL,
CONSTRAINT MOD_UNIQUE UNIQUE (MODELNAME, ITEMID));
Пример 4.29. Таблица с полем массивом
CREATE TABLE JOB ( JOB_CODE JOBCODE NOT NULL, JOB_GRADE JOBGRADE NOT NULL, JOB_COUNTRY COUNTRYNAME, JOB_TITLE VARCHAR(25) NOT NULL, MIN_SALARY NUMERIC(18, 2) DEFAULT 0 NOT NULL, MAX_SALARY NUMERIC(18, 2) NOT NULL, JOB_REQUIREMENT BLOB SUB_TYPE 1, LANGUAGE_REQ VARCHAR(15) [1:5], PRIMARY KEY (JOB_CODE, JOB_GRADE, JOB_COUNTRY), FOREIGN KEY (JOB_COUNTRY) REFERENCES COUNTRY (COUNTRY) ON UPDATE CASCADE ON DELETE SET NULL, CONSTRAINT CHK_SALARY CHECK (MIN_SALARY < MAX_SALARY) );
Пример 4.30. Создание таблицы с ограничением первичного, внешнего и уникального ключа для которых заданы пользовательские имена индексов
CREATE TABLE PROJECT ( PROJ_ID PROJNO NOT NULL, PROJ_NAME VARCHAR(20) NOT NULL UNIQUE USING DESC INDEX IDX_PROJNAME, PROJ_DESC BLOB SUB_TYPE 1, TEAM_LEADER EMPNO, PRODUCT PRODTYPE, CONSTRAINT PK_PROJECT PRIMARY KEY (PROJ_ID) USING INDEX IDX_PROJ_ID, FOREIGN KEY (TEAM_LEADER) REFERENCES EMPLOYEE (EMP_NO) USING INDEX IDX_LEADER );
Пример 4.31. Создание таблицы с вычисляемыми полями
CREATE TABLE SALARY_HISTORY ( EMP_NO EMPNO NOT NULL, CHANGE_DATE TIMESTAMP DEFAULT 'NOW' NOT NULL, UPDATER_ID VARCHAR(20) NOT NULL, OLD_SALARY SALARY NOT NULL, PERCENT_CHANGE DOUBLE PRECISION DEFAULT 0 NOT NULL, SALARY_CHANGE GENERATED ALWAYS AS (OLD_SALARY * PERCENT_CHANGE / 100), NEW_SALARY COMPUTED BY (OLD_SALARY + OLD_SALARY * PERCENT_CHANGE / 100) );
Поле SALARY_CHANGE объявлено согласно стандарту SQL::2003, поле NEW_SALARY в классическом стиле объявления вычисляемых полей в Firebird.
Если в операторе создания таблицы указано необязательное предложение GLOBAL TEMPORARY, то вместо обычной таблицы будет создана глобальная временная таблица. Глобальные временные таблицы (в дальнейшем сокращённо GTT) так же, как и обычные таблицы, являются постоянными метаданными, но данные в них ограничены по времени существования транзакцией (значение по умолчанию) или соединением с БД. Каждая транзакция или соединение имеет свой собственный экземпляр GTT с данными, изолированный от всех остальных. Экземпляры создаются только при условии обращения к GTT, и данные в ней удаляются при подтверждении транзакции или отключении от БД.
Если в операторе создания глобальной временной таблицы указано необязательное предложение ON COMMIT DELETE ROWS, то будет создана GTT транзакционного уровня (по умолчанию). При указании предложения ON COMMIT PRESERVE ROWS – будет создана GTT уровня соединения с базой данных.
Предложение EXTERNAL [FILE] нельзя использовать для глобальной временной таблицы.
Операторы COMMIT RETAINING и ROLLBACK RETAINING не сохраняют данные в глобальных временных таблицах объявленных как ON COMMIT DELETE ROWS. Это поведение было признано ошибочным и оно изменено в Firebird 3.x. Кроме того до версии 2.5.9 дисковое пространство не освобождалось при выполнении COMMIT RETAINING и ROLLBACK RETAINING.
Глобальные временные таблицы имеют ряд ограничений:
GTT и обычные таблицы не могут ссылаться друг на друга;
GTT уровня соединения ("PRESERVE ROWS") GTT не могут ссылаться на GTT транзакционного уровня ("DELETE ROWS");
Уничтожения экземпляра GTT в конце своего жизненного цикла не вызывает срабатывания триггеров до/после удаления.
Пример 4.32. Создание глобальной временной таблицы уровня соединения
CREATE GLOBAL TEMPORARY TABLE MYCONNGTT (
ID INTEGER NOT NULL PRIMARY KEY,
TXT VARCHAR(32),
TS TIMESTAMP DEFAULT CURRENT_TIMESTAMP);
ON COMMIT PRESERVE ROWS;
Пример 4.33. Создание глобальной временной таблицы уровня транзакции ссылающейся внешним ключом на глобальную временную таблицу уровня соединения.
CREATE GLOBAL TEMPORARY TABLE MYTXGTT (
ID INTEGER NOT NULL PRIMARY KEY,
PARENT_ID INTEGER NOT NULL REFERENCES MYCONNGTT(ID),
TXT VARCHAR(32),
TS TIMESTAMP DEFAULT CURRENT_TIMESTAMP);
Необязательное предложение EXTERNAL [FILE] указывает, что таблица хранится вне базы данных во внешнем текстовом файле. Столбцы таблицы, хранящейся во внешнем файле, могут быть любого типа за исключением BLOB и массивов с любым типом данных.
Над таблицей, хранящейся во внешнем файле, допустимы только операции добавления новых строк (INSERT) и выборки (SELECT) данных. Операции же изменения существующих данных (UPDATE) или удаления строк такой таблицы (DELETE) не могут быть выполнены.
Внешняя таблица не может содержать ограничений первичного, внешнего и уникального ключа. Для полей такой таблицы невозможно создать индексы.
Файл с внешней таблицей должен располагаться на устройстве хранения, физически
расположенном на сервере, на котором расположена СУБД. Если параметр
ExternalFileAccess
в файле конфигурации
firebird.conf
содержит Restrict
, то файл
внешней таблицы должен находится в одном из каталогов, указанных в качестве аргумента
Restrict
. Если при обращении к таблице Firebird не находит файла,
то он создаёт его при первом обращении.
Возможность использования для таблиц внешних файлов зависит от установки значения
параметра ExternalFileAccess
в файле конфигурации
firebird.conf
:
Если он установлен в значение None
, то запрещён любой
доступ к внешнему файлу.
Значение Restrict
рекомендуется для ограничения доступа к
внешним файлам только каталогами, созданными специально для этой цели
администратором сервера. Например:
ExternalFileAccess = Restrict externalfiles
ограничит доступ директорией externalfiles
корневого
каталога Firebird.
ExternalFileAccess = Restrict d:\databases\outfiles;
e:\infiles
ограничит доступ только двумя директориями Windows.
Обратите внимание, что любые пути являющиеся отображением сетевых путей не
будут работать. Также не будут работать пути заключённые в одинарные или
двойные кавычки.
Значение Full
позволяет доступ к внешним файлам в любом
месте файловой системы хоста. Это создаёт уязвимость и не рекомендуется к
использованию.
Внешняя таблица имеет формат «строк» c фиксированной длинной. Нет никаких разделителей полей: границы полей и строк определяются максимальными размерами в байтах в определении каждого поля. Это необходимо помнить и при определении структуры внешней таблицы, и при проектировании входного файла для внешней таблицы, в которую должны импортироваться данные из другого приложения. Например, широко распространённый формат «.csv», не может быть использован в качестве входного файла, и не может быть получен непосредственно как внешний файл.
Самым полезным типом данных для столбцов внешних таблиц является тип CHAR с фиксированной длинной, длинна должна подходить под данные с которыми необходимо работать. Числовые типы и даты легко преобразуются в них, строки получаются как есть, в то время как, если данные не читаются другой базой данных Firebird, то родные типы могут быть нераспознаваемыми дня внешних приложений и являться для них «абракадаброй».
Конечно, существуют способы манипулирования типами данных так, чтобы создавать выходные файлы из Firebird, которые могут быть непосредственно прочитаны как входные файлы в других приложениях, используя хранимые процедуры с использованием внешних таблиц или без них. Описания этих методов выходит за рамки данного руководства. Здесь мы приведём лишь некоторые рекомендации и советы для создания и работы с простыми текстовыми файлами, поскольку внешняя таблица часто используется как простой способ для создания или чтения транзакционно-независимого журнала. Эти файлы могут быть прочитаны в оффлайн режиме текстовым редактором или приложением аудита.
Как правило, внешние файлы более удобны если строки разделены разделителем, в виде последовательности "новой строки", которая может быть распознана приложением на предназначенной платформе. Для Windows — это двухбайтная 'CRLF' последовательность, возврат каретки (ASCII код 13) и перевод строки (ASCII код 10). Для POSIX — LF обычно самодостаточен, в некоторых MacOS X приложениях она может быть LFCR. Существуют различные способы для автоматического заполнения столюца разделителя. В нашем примере это сделано с помощью BEFORE INSERT триггера и встроенной функции ASCII_CHAR.
В нашем примере мы будем определять внешнюю таблицу журнала, которая может быть использована в обработчике исключений внутри хранимой процедуры или триггера. Внешняя таблица выбрана потому, что сообщения из любых обрабатываемых исключений будут сохранены в журнале, даже если транзакция, в которой был запущен процесс, будет откачена из-за другого необработанного исключения. В целях демонстрации наша таблица содержит всего два столбца: метку времени и текстовое сообщение. Третий столбец хранит разделитель строки:
CREATE TABLE ext_log EXTERNAL FILE 'd:\externals\log_me.txt' ( stamp CHAR(24), message CHAR(100), crlf CHAR(2) -- Для Windows ); COMMIT;
Теперь создадим триггер, для автоматического сохранения метки времени и разделителя строки, каждый раз когда сообщение записывается в таблицу:
SET TERM ^; CREATE TRIGGER bi_ext_log FOR ext_log ACTIVE BEFORE INSERT AS BEGIN IF (NEW.stamp IS NULL) THEN NEW.stamp = CAST (CURRENT_TIMESTAMP AS CHAR(24)); NEW.crlf = ASCII_CHAR(13) || ASCII_CHAR(10); END ^ COMMIT ^ SET TERM ;^
Вставка некоторых записей (это может быть сделано в обработчике исключения):
INSERT INTO ext_log (message) VALUES('Shall I compare thee to a summer''s day?'); INSERT INTO ext_log (message) VALUES('Thou art more lovely and more temperate');
Содержимое внешнего файла:
2015-10-07 15:19:03.4110Shall I compare thee to a summer's day? 2015-10-07 15:19:58.7600Thou art more lovely and more temperate
См. также: ALTER TABLE, DROP TABLE, CREATE DOMAIN.
Назначение: Изменение структуры таблицы.
Доступно в: DSQL, ESQL.
Синтаксис:
ALTER TABLEtablename
<operation>
[,<operation>
];<operation>
::= ADD<col_def>
| ADD<tconstraint>
| DROPcolname
| DROP CONSTRAINTconstr_name
| ALTER [COLUMN]colname
<col_mod>
<col_def>
::=<regular_col_def>
|<computed_col_def>
<regular_col_def>
::=colname
{<datatype>
|domainname
} [DEFAULT {literal
| NULL |<context_var>
}] [NOT NULL] [<col_constraint>
] [COLLATEcollation_name
]<computed_col_def>
::=colname
[<datatype>
] {COMPUTED [BY] | GENERATED ALWAYS AS} (<expression>
)<col_mod>
::=<regular_col_mod>
|<computed_col_mod>
<regular_col_mod>
::= TOnewname
| POSITIONnewpos
| TYPE {<datatype>
|domainname
} | SET DEFAULT {literal
| NULL |<context_var>
} | DROP DEFAULT<computed_col_mod>
::= TOnewname
| POSITIONnewpos
| [TYPE<datatype>
] {GENERATED ALWAYS AS | COMPUTED [BY]} (<expression>
)<datatype>
::= { {SMALLINT | INT[EGER] | BIGINT} [<array_dim>
] | {FLOAT | DOUBLE PRECISION} [<array_dim>
] | {DATE | TIME | TIMESTAMP} [<array_dim>
] | {DECIMAL | NUMERIC} [(precision
[,scale
])] [<array_dim>
] | {CHAR | CHARACTER | CHARACTER VARYING | VARCHAR} [(size
)] [<array_dim>
] [CHARACTER SETcharset_name
] | {NCHAR | NATIONAL CHARACTER | NATIONAL CHAR} [VARYING] [(size
)] [<array_dim>
] | BLOB [SUB_TYPE {subtype_num
|subtype_name
}] [SEGMENT SIZEseglen
] [CHARACTER SETcharset_name
] | BLOB [(seglen
[,subtype_num
])] }<array_dim>
::= [[m
:]n
[,[m
:]n
...]]<col_constraint>
::= [CONSTRAINTconstr_name
] { UNIQUE [<using_index>
] | PRIMARY KEY [<using_index>
] | REFERENCES other_table [(other_col
)] [ON DELETE { NO ACTION | CASCADE | SET DEFAULT | SET NULL}] [ON UPDATE { NO ACTION | CASCADE | SET DEFAULT | SET NULL}] [<using_index>
] | CHECK (<check_condition>
) }<tconstraint>
::= [CONSTRAINTconstr_name
] { UNIQUE (<col_list>
) [<using_index>
] | PRIMARY KEY (<col_list>
) [<using_index>
] | FOREIGN KEY (<col_list>
) REFERENCESother_table
[(<col_list>
)] [ON DELETE { NO ACTION | CASCADE | SET DEFAULT | SET NULL}] [ON UPDATE { NO ACTION | CASCADE | SET DEFAULT | SET NULL}] [<using_index>
] | CHECK (<check_condition>
) }<col_list>
::=colname
[,colname
...]<using_index>
::= USING [ASC[ENDING] | DESC[ENDING]] INDEXindexname
<check_condition>
::= {<val>
<operator>
<val>
|<val>
[NOT] BETWEEN<val>
AND<val>
|<val>
[NOT] IN (<val>
[,<val>
...] |<select_list>
) |<val>
IS [NOT] NULL |<val>
IS [NOT] DISTINCT<val>
|<val>
[NOT] CONTAINING<val>
|<val>
[NOT] STARTING [WITH]<val>
|<val>
[NOT] LIKE<val>
[ESCAPE<val>
] |<val>
[NOT] SIMILAR TO<val>
[ESCAPE<val>
] |<val>
<operator>
{ALL | SOME | ANY} (<select_list>
) | [NOT] EXISTS (<select_expr>
) | [NOT] SINGULAR (<select_expr>
) | (<check_condition>
) | NOT<check_condition>
|<check_condition>
OR<check_condition>
|<check_condition>
AND<check_condition>
}<operator>
::= <> | != | ^= | ~= | = | < | > | <= | >= | !< | ^< | ~< | !> | ^> | ~><val>
::=colname
[[<array_idx>
[,<array_idx>
...]]] |literal
|<context_var>
|<expression>
| NULL | NEXT VALUE FORgenname
| GEN_ID(genname
,<val>
) | CAST(<val>
AS<datatype>
) | (<select_one>
) |func
(<val>
[,<val>
...])
Таблица 4.9. Параметры оператора ALTER TABLE
Параметр | Описание |
---|---|
tablename |
Имя таблицы. |
<operation> |
Одна из допустимых операций по изменению структуры таблицы. |
colname |
Имя столбца таблицы, может содержать до 31 байта. Должно быть уникальным внутри таблицы. |
newname |
Новое имя столбца таблицы, может содержать до 31 байта. Должно быть уникальным внутри таблицы. |
newpos |
Новая позиция столбца в таблице. Целое число в диапазоне от 1 до количества столбцов таблицы. |
<datatype> |
Тип данных SQL. |
domain_name |
Имя домена. |
<col_constraint> |
Ограничение столбца. |
<tconstraint> |
Ограничение таблицы. |
constr_name |
Имя ограничения, может содержать до 31 байта. |
other_table |
Имя таблицы, на которую ссылается внешний ключ. |
other_col |
Столбец таблицы, на которую ссылается внешний ключ. |
<using_index> |
Позволяет задать имя автоматически создаваемого индекса для ограничения, и опционально определить, какой это будет индекс — по возрастанию (по умолчанию) или по убыванию. |
literal |
Литерал. |
context_var |
Любая контекстная переменная, тип которой совместим с типом данных столбца. |
<check_condition> |
Условие проверки ограничения. Выполняется, если оценивается как TRUE или NULL/UNKNOWN. |
collation_name |
Имя порядка сортировки. Необходимо указывать если вы хотите чтобы порядок сортировки для столбца отличался от порядка сортировки для набора символов по умолчанию этого столбца. |
<array_dim> |
Размерность массива. |
n |
Начальный номер элемента в массиве, положительное целое число. |
m |
Последний номер элемента в массиве, положительное целое число. |
precision |
Точность. От 1 до 18. |
scale |
Масштаб. От 0 до 18, должно быть меньше или равно
|
size |
Максимальный размер строки в символах. |
charset_name |
Имя набора символов. Необходимо указывать, если вы хотите чтобы набор символов столбца отличался от набора символов по умолчанию для базы данных. |
subtype_num |
Номер подтипа BLOB. См. Подтипы BLOB. |
subtype_name |
Мнемоника подтипа BLOB. См. Подтипы BLOB. |
seglen |
Размер сегмента, не может превышать 65535. |
<select_one> |
Оператор SELECT выбирающий один столбец и возвращающий только одну строку. |
<select_list> |
Оператор SELECT выбирающий один столбец и возвращающий ноль и более строк. |
<select_expr> |
Оператор SELECT выбирающий несколько столбцов и возвращающий ноль и более строк. |
<experssion> |
Выражение. |
genname |
Имя последовательности (генератора). |
func |
Скалярная функция или UDF. |
Оператор ALTER TABLE изменяет структуру существующей таблицы. Одиночный оператор ALTER TABLE позволяет производить множество операций добавления/удаления столбцов и ограничений, а также модификаций столбцов. Список операций выполняемых при модификации таблицы разделяется запятой.
Некоторые изменения структуры таблицы увеличивают счётчик форматов, закреплённый за каждой таблицей. Количество форматов для каждой таблицы ограничено значением 255. После того, как счётчик форматов достигнет этого значения, вы не сможете больше менять структуру таблицы.
Для сброса счётчика форматов необходимо сделать резервное копирование и восстановление базы данных (утилитой gbak).
Предложение ADD позволяет добавить новый столбец или новое ограничение таблицы. Синтаксис определения столбца и синтаксис описания ограничения таблицы полностью совпадают с синтаксисом, описанным в операторе CREATE TABLE.
Воздействие на счётчик ссылок:
При каждом добавлении нового столбца номер формата увеличивается на единицу.
Добавление нового ограничения таблицы не влечёт за собой увеличение номера формата.
Будьте аккуратны при добавлении нового столбца с установленным ограничением NOT NULL. Это может привести к нарушению логической целостности данных. При добавлении такого столбца рекомендуется либо указывать ему значение по умолчанию, либо обновлять строки таблицы для присвоения ему значений отличных от NULL.
Кроме того, при добавлении нового ограничения CHECK не осуществляется проверка соответствия ему ранее внесённых данных. Поэтому перед добавлением такого ограничения рекомендуем производить предварительную проверку данных в таблице.
Предложение DROP удаляет указанный столбец таблицы. Столбец таблицы не может быть удалён, если от него существуют зависимости. Другими словами для успешного удаления столбца на него должны отсутствовать ссылки. Ссылки на столбец могут содержаться:
в ограничениях столбцов или таблицы;
в индексах;
в хранимых процедурах и триггерах;
в представлениях.
При каждом удалении столбца номер формата увеличивается на единицу.
Предложение DROP CONSTRAINT удаляет указанное ограничение столбца или таблицы. Ограничение первичного ключа или уникального ключа не могут быть удалены, если они используются в ограничении внешнего ключа другой таблицы. В этом случае, необходимо удалить ограничение FOREIGN KEY до удаления PRIMARY KEY или UNIQUE ключа, на которые оно ссылается.
Удаление ограничения столбца или ограничения таблицы не влечёт за собой увеличение номера формата.
Предложение ALTER [COLUMN] позволяет изменить следующие характеристики существующих столбцов:
изменение имени (не изменяет номер формата);
изменение типа данных (увеличивает номер формата на единицу);
изменение позиции столбца в списке столбцов таблицы (не изменяет номер формата);
удаление значения по умолчанию столбца (не изменяет номер формата);
добавление значения по умолчанию столбца (не изменяет номер формата);
изменение типа и выражения для вычисляемого столбца (не изменяет номер формата).
Ключевое слово TO переименовывает существующий столбец. Новое имя столбца не должно присутствовать в таблице.
Невозможно изменение имени столбца, если этот столбец включён в какое-либо ограничение — первичный или уникальный ключ, внешний ключ, ограничение столбца или проверочное ограничение таблицы CHECK. Имя столбца также нельзя изменить, если этот столбец таблицы используется в каком-либо триггере, в хранимой процедуре или представлении.
Ключевое слово TYPE изменяет тип существующего столбца на другой допустимый тип. Не допустимы любые изменения типа, которые могут привести к потере данных. Например, количество символов в новом типе для столбца не может быть меньше, чем было установлено ранее.
Если столбец был объявлен как массив, то изменить ни его тип, ни размерность нельзя.
Нельзя изменить тип данных у столбца, который принимает участие в связке внешний ключ / первичный (уникальный) ключ.
Ключевое слово POSITION изменяет позицию существующего столбца. Позиции столбцов нумеруются с единицы.
Если будет задан номер позиции меньше 1, то будет выдано соответствующее сообщение об ошибке.
Если будет задан номер позиции, превышающий количество столбцов в таблице, то изменения не будут выполнены, но ни ошибки, ни предупреждения не последуют.
Предложение DROP DEFAULT удаляет значение по умолчанию для столбца таблицы.
Если столбец основан на домене со значением по умолчанию — доменное значение перекроет это удаление.
Если удаление значения по умолчанию производится над столбцом, у которого нет значения по умолчанию, или чьё значение по умолчанию основано на домене, то это приведёт к ошибке выполнения данного оператора.
Предложение SET DEFAULT устанавливает значение по умолчанию для столбца таблицы. Если столбец уже имел значение по умолчанию, то оно будет заменено новым. Значение по умолчанию для столбца всегда перекрывает доменное значение по умолчанию.
Для вычисляемых столбцов (GENERATED ALWAYS AS или COMPUTED BY) позволяется изменить тип и выражение вычисляемого столбца. Невозможно изменить обычный столбец на вычисляемый и наоборот.
На данный момент не существует возможности:
Установить и снять ограничение NOT NULL для столбца таблицы.
Изменить сортировку по умолчанию для столбцов символьных типов.
Только владелец таблицы и администраторы имеют привилегии на использование ALTER TABLE.
Пример 4.35. Добавление столбца с ограничением уникальности и удаление другого столбца
ALTER TABLE COUNTRY
ADD CAPITAL VARCHAR(25) UNIQUE,
DROP CURRENCY;
Пример 4.36. Добавление столбца с ограничением NOT NULL
ALTER TABLE OBJECTS ADD QUANTITY INT NOT NULL;
Если в таблице OBJECTS уже есть данные, то после добавления NOT NULL столбца, обязательно проставьте ему значение по умолчанию или обновите все строки таблицы каким-нибудь значением. Иначе это приведёт к так называемой "невосстановимой" резервной копии, сделанной с помощью утилиты gbak (на самом деле его можно восстановить, см. ключ -N).
UPDATE OBJECTS
SET QUANTITY = 1;
Пример 4.37. Добавление проверочного ограничения и внешнего ключа
ALTER TABLE JOB ADD CONSTRAINT CHK_SALARY CHECK (MIN_SALARY < MAX_SALARY), ADD FOREIGN KEY (JOB_COUNTRY) REFERENCES COUNTRY (COUNTRY);
Пример 4.38. Модификация сразу нескольких столбцов таблицы
ALTER TABLE STOCK
ALTER COLUMN MODEL SET DEFAULT 1,
ALTER COLUMN ITEMID TYPE BIGINT,
ALTER COLUMN ITEMID NULL,
ALTER COLUMN MODELNAME TO NAME;
Пример 4.39. Изменение вычисляемых столбцов
ALTER TABLE SALARY_HISTORY ALTER NEW_SALARY GENERATED ALWAYS AS (OLD_SALARY + OLD_SALARY * PERCENT_CHANGE / 100), ALTER SALARY_CHANGE COMPUTED BY (OLD_SALARY * PERCENT_CHANGE / 100);
См. также: CREATE TABLE, RECREATE TABLE.
Назначение: Удаление существующей таблицы.
Доступно в: DSQL, ESQL.
Синтаксис:
DROP TABLE tablename
;
Оператор DROP TABLE удаляет существующую таблицу. Если таблица имеет зависимости, то удаление не будет произведено. При удалении таблицы будут также удалены все триггеры на её события и индексы, построенные для её полей.
Только владелец таблицы и администраторы имеют привилегии на использование DROP TABLE.
Назначение: Создание новой таблицы или пересоздание существующей.
Доступно в: DSQL.
Синтаксис:
RECREATE [GLOBAL TEMPORARY] TABLEtablename
[EXTERNAL [FILE] '<filespec>
'] (<col_def>
[, {<col_def>
|<tconstraint>
} ...]) [ON COMMIT {DELETE | PRESERVE} ROWS];
Полное описание определений столбцов и ограничений таблицы смотрите в разделе CREATE TABLE.
Оператор RECREATE TABLE создаёт или пересоздаёт таблицу. Если таблица с таким именем уже существует, то оператор RECREATE TABLE попытается удалить её и создать новую. Оператор RECREATE TABLE не выполнится, если существующая таблица имеет зависимости.
Пример 4.41. Создание или пересоздание таблицы
RECREATE TABLE COUNTRY (
COUNTRY COUNTRYNAME NOT NULL PRIMARY KEY,
CURRENCY VARCHAR(10) NOT NULL);
См. также: CREATE TABLE, DROP TABLE.
Индекс (index) — объект базы данных, предназначенный для ускорения выборки данных из таблицы и/или для ускорения упорядочения результатов выборки данных из таблицы. Кроме того, индексы используются для обеспечения ограничений целостности — PRIMARY KEY, FOREIGN KEY, UNIQUE.
В данном разделе описываются вопросы создания индексов, перевода их в активное/неактивное состояние, удаление индексов и сбор статистики (пересчёт селективности) для индексов.
Назначение: Создание индекса для таблицы.
Доступно в: DSQL, ESQL.
Синтаксис:
CREATE [UNIQUE] [ASC[ENDING] | DESC[ENDING]] INDEXindexname
ONtablename
{(col
[,col
…]) | COMPUTED BY (<expression>
)};
Таблица 4.11. Параметры оператора CREATE INDEX
Параметр | Описание |
---|---|
indexname |
Имя индекса. Может содержать до 31 байта. |
tablename |
Имя таблицы, для которой строится индекс. |
col |
Столбец таблицы. В качестве столбцов не могут быть использованы поля типа BLOB, ARRAY и вычисляемые поля. |
expression |
Выражение, содержащее столбцы таблицы. |
Оператор CREATE INDEX создаёт индекс для таблицы, который может быть использован для ускорения поиска, сортировки и/или группирования. Кроме того, индекс может быть использован при определении ограничений, таких как первичный ключ, внешний ключ или ограничениях уникальности. Индекс может быть построен на столбцах любого типа кроме BLOB и массивов. Имя индекса должно быть уникальным среди всех имён индексов.
При добавлении ограничений первичного ключа, внешнего ключа или ограничения уникальности будет неявно создан одноименный индекс. Так, например, при выполнении следующего оператора будет неявно создан индекс PK_COUNTRY.
ALTER TABLE COUNTRY ADD CONSTRAINT PK_COUNTRY PRIMARY KEY (ID);
Если при создании индекса указано ключевое слово UNIQUE, то индекс гарантирует уникальность значений ключей. Такой индекс называется уникальным. Уникальный индекс не является ограничением уникальности.
Уникальные индексы не могут содержать дубликаты значений ключей, но могут содержать дубликаты значения NULL в соответствии со стандартом SQL-99 (в том числе и в многосегментном индексе).
Индекс может быть построен в восходящем (ASCENDING) и нисходящем (DESCENDING) порядке.
Ключевое слово ASCENDING (сокращённо ASC), обозначает, что ключи индекса расположены по возрастанию значений. Такое расположение ключей используется по умолчанию.
Ключевое слово DESCENDING (сокращённо DESC), обозначает, что ключи индекса расположены по убыванию значений.
При создании индекса вместо одного или нескольких столбцов вы также можете указать одно выражение, используя предложение COMPUTED BY. Такой индекс называется вычисляемым или индексом по выражению. Вычисляемые индексы используются в запросах, в которых условие в предложениях WHERE, ORDER BY или GROUP BY в точности совпадает с выражением в определении индекса. Выражение в вычисляемом индексе может использовать несколько столбцов таблицы.
Не смотря на то, что можно создать вычисляемый индекс по вычисляемому полю, использоваться такой индекс не будет до версии 2.5.9.
Максимальная длина ключа индекса ограничена 1/4 размера страницы.
Максимальная длина индексируемой строки на 9 байтов меньше, чем максимальная длина ключа. Максимальная длина индексируемой строки зависит от размера страницы и набора символов.
Таблица 4.12. Длина индексируемой строки и набор символов
Размер страницы | Максимальная длина индексируемой строки для набора символов, байт/символ | ||||
---|---|---|---|---|---|
1 | 2 | 3 | 4 | 6 | |
4096 | 1015 | 507 | 338 | 253 | 169 |
8192 | 2039 | 1019 | 679 | 509 | 339 |
16384 | 4087 | 2043 | 1362 | 1021 | 682 |
Для каждой таблицы максимально возможное количество индексов ограничено и зависит от размера страницы и количества столбцов в индексе.
Таблица 4.13. Число индексов и количество столбцов
Размер страницы | Число индексов в зависимости от количества столбцов в индексе | ||
---|---|---|---|
1 | 2 | 3 | |
4096 | 203 | 145 | 113 |
8192 | 408 | 291 | 227 |
16384 | 818 | 584 | 454 |
Только владелец таблицы для которой создаётся индекс и администраторы имеют привилегии на использование CREATE INDEX.
Пример 4.43. Создание индекса с сортировкой ключей по убыванию
CREATE DESCENDING INDEX IDX_CHANGE ON SALARY_HISTORY (CHANGE_DATE);
Пример 4.44. Создание многосегментного индекса
CREATE INDEX IDX_SALESTAT ON SALES (ORDER_STATUS, PAID);
Пример 4.45. Создание индекса, не допускающего дубликаты значений
CREATE UNIQUE INDEX UNQ_COUNTRY_NAME ON COUNTRY (NAME);
Пример 4.46. Создание вычисляемого индекса
CREATE INDEX IDX_NAME_UPPER ON PERSONS COMPUTED BY (UPPER (NAME));
Такой индекс может быть использован для регистронезависимого поиска.
SELECT *
FROM PERSONS
WHERE UPPER(NAME) STARTING WITH UPPER('Iv');
См. также: ALTER INDEX, DROP INDEX.
Назначение: Перевод индекса в активное/неактивное состояние, перестройка индекса.
Доступно в: DSQL, ESQL.
Синтаксис:
ALTER INDEX indexname
{ACTIVE | INACTIVE};
Оператор ALTER INDEX переводит индекс в активное/неактивное состояние. Возможность изменения структуры и порядка сортировки ключей этот оператор не предусматривает.
При выборе опции INACTIVE, индекс переводится из активного в неактивное состояние. Перевод индекса в неактивное состояние по своему действию похоже на команду DROP INDEX за исключением того, что определение индекса сохраняется в базе данных. Невозможно перевести в неактивное состояние индекс участвующий в ограничении.
Перевод индекса в неактивное состояние может быть полезен при массовой вставке, модификации или удалении записей из таблицы, для которой этот индекс построен.
При выборе альтернативы ACTIVE индекс переводится из неактивного состояния в активное. При переводе индекса из неактивного состояния в активное индекс перестраивается.
Даже если индекс находится в активном состоянии оператор ALTER INDEX ACTIVE всё равно перестраивает индекс. Таким образом, эту команду можно использовать для перестройки индексов, автоматически созданных для ограничений PRIMARY KEY, FOREIGN KEY, UNIQUE, для которых выполнение оператора ALTER INDEX INACTIVE невозможно.
Только владелец таблицы для которой был создан индекс и администраторы имеют привилегии на использование ALTER INDEX.
Назначение: Удаление индекса из базы данных.
Доступно в: DSQL, ESQL.
Синтаксис:
DROP INDEX indexname
;
Оператор DROP INDEX удаляет существующий индекс из базы данных. При наличии зависимостей для существующего индекса (если он используется в ограничении) удаление не будет выполнено.
Только владелец таблицы для которой был создан индекс и администраторы имеют привилегии на использование DROP INDEX.
Назначение: Пересчёт селективности индекса.
Доступно в: DSQL, ESQL.
Синтаксис:
SET STATISTICS INDEX indexname
;
Оператор SET STATISTICS пересчитывает значение селективности для указанного индекса.
Селективность (избирательность) индекса — это оценочное количество строк, которые могут быть выбраны при поиске по каждому значению индекса. Уникальный индекс имеет максимальную селективность, поскольку при его использовании невозможно выбрать более одной строки для каждого значения ключа индекса. Актуальность селективности индекса важна для выбора наиболее оптимального плана выполнения запросов оптимизатором.
Пересчёт селективности индекса может потребоваться после массовой вставки, модификации или удалении большого количества записей из таблицы, поскольку она становится неактуальной.
Отметим, что в Firebird статистика индексов автоматически не пересчитывается ни после массовых изменений данных, ни при каких либо других условиях. При создании (CREATE) или его активации (ALTER INDEX ACTIVE) статистика индекса полностью соответствует его содержимому.
Только владелец таблицы для которой был создан индекс и администраторы имеют привилегии на использование SET STATISTICS INDEX.
См. также: CREATE INDEX, ALTER INDEX.
Представление (view) — виртуальная таблица, которая по своей сути является именованным запросом SELECT выборки данных произвольной сложности. Выборка данных может осуществляться из одной и более таблиц, других представлений, а также селективных хранимых процедур.
В отличие от обычных таблиц реляционных баз данных, представление не является самостоятельным набором данных, хранящимся в базе данных. Результат в виде набора данных динамически создаётся при обращении к представлению.
Метаданные представлений доступны для генерации двоичного кода хранимых процедур и триггеров так, как будто они являются обычной таблицей, хранящей постоянные данные.
Назначение: Создание нового представления.
Доступно в: DSQL.
Синтаксис:
CREATE VIEWviewname
[<full_column_list>
] AS<select_statement>
[WITH CHECK OPTION];<full_column_list>
::= (colname
[,colname
...])
Таблица 4.17. Параметры оператора CREATE VIEW
Параметр | Описание |
---|---|
viewname |
Имя представления. Может содержать до 31 байта. |
select_statement |
Оператор SELECT. |
full_column_list |
Список столбцов представления. |
colname |
Имя столбца представления. Дубликаты имён столбцов не позволяются. |
Оператор CREATE VIEW создаёт новое представление. Имя представления должно быть уникальным среди имён всех представлений, таблиц и хранимых процедур базы данных.
После имени создаваемого представления может идти список имён столбцов, получаемых в результате обращения к представлению. Имена в списке могут быть никак не связаны с именами столбцов базовых таблиц. При этом их количество должно точно соответствовать количеству столбцов в списке выбора главного оператора SELECT представления.
Если список столбцов представления отсутствует, то будут использоваться имена столбцов базовых таблиц или псевдонимов (алиасов) полей оператора SELECT. Если имена полей повторяются или присутствуют выражения столбцов без псевдонимов, которые делают невозможным получение допустимого списка столбцов, то создание представления завершается ошибкой.
Количество столбцов в списке столбцов представления должно совпадать с количеством столбцов указанном в списке выбора оператора SELECT указанного в определении представления.
Если указан полный список столбцов, то задание псевдонимов в операторе SELECT не имеет смысла, поскольку они будут переопределены именами из списка столбцов;
Список столбцов необязателен при условии, что все столбцы в операторе SELECT имеют явное имя, и эти имена будут уникальными в списке столбцов.
Представление может быть обновляемым и только для чтения. Если представление обновляемое, то данные, полученные при обращении к такому представлению, можно изменить при помощи DML операторов INSERT, UPDATE, DELETE, UPDATE OR INSERT, MERGE. Изменения, выполняемые над представлением, применяются к базовой таблице(ам).
Представление только для чтения можно сделать обновляемым при помощи вспомогательных триггеров. После того как на представлении будет определён один или несколько триггеров, то изменения не будут автоматически попадать в базовую таблицу, даже если перед этим представление было обновляемым. В этом случае ответственность за обновление (удаление или вставку) записей базовых таблиц, лежит на программисте, определяющем триггеры.
Для того чтобы представление было обновляемым, необходимо выполнение следующих условий:
оператор выборки SELECT обращается только к одной таблице или одному изменяемому представлению;
оператор выборки SELECT не должен обращаться к хранимым процедурам;
все столбцы базовой таблицы или обновляемого представления, которые не присутствуют в данном представлении, должны удовлетворять одному из следующих условий:
позволять значение NULL
NOT NULL столбцы должны иметь значение по умолчанию
значение NOT NULL столбцов должны быть инициализированы в триггерах базовых таблиц
оператор выборки SELECT не содержит полей определённых через подзапросы или другие выражения;
оператор выборки SELECT не содержит полей определённых через агрегатные функции (MIN, MAX, AVG, COUNT, LIST);
оператор выборки SELECT не содержит предложений ORDER BY, GROUP BY, HAVING;
оператор выборки SELECT не содержит ключевого слова DISTINCT и ограничений количества строк с помощью ключевых слов ROWS, FIRST, SKIP.
Необязательное предложение WITH CHECK OPTIONS задаёт для изменяемого представления требования проверки вновь введённых или модифицируемых данных условию, указанному в предложении WHERE оператора выборки SELECT. При попытке вставки новой записи или модификации записи проверяется, выполняется ли для этой записи условие в предложении WHERE, если условие не выполняется, то вставка/модификация не выполняется и будет выдано соответствующее диагностическое сообщение.
Предложение WITH CHECK OPTION может задаваться в операторе создания представления только в том случае, если в главном операторе SELECT представления указано предложение WHERE. Иначе будет выдано сообщение об ошибке.
Если используется предложение WITH CHECK OPTIONS, то система проверяет входные значение на соответствие условию в предложении WHERE до того как они будут переданы в базовую таблицу. Таким образом, если входные значения не проходят проверку, то предложения DEFAULT или триггеры на базовой таблице, не могут исправить входные значения, поскольку действия никогда не будут выполнены.
Кроме того, поля представления не указанные в операторе INSERT передаются в базовую таблицу как значения NULL, независимо от их наличия или отсутствия в предложении WHERE. В результате значения по умолчанию, определённые на таких полях базовой таблицы, не будут применены. С другой стороны, триггеры будут вызываться и работать как ожидалось.
Для представлений у которых отсутствует предложение WITH CHECK OPTIONS, поля, отсутствующие в операторе INSERT, не передаются вовсе, поэтому любые значения по умолчанию будут применены.
Создать новое представление может любой пользователь, подключeнный к базе данных.
Пользователь, создавший представление, становится его владельцем.
Для создания представления пользователями, которые не имеют административных привилегий, необходимы также привилегии на чтение (SELECT) данных из базовых таблиц и представлений, и привилегии на выполнение (EXECUTE) используемых селективных хранимых процедур.
Для разрешения вставки, обновления и удаления через представление, необходимо чтобы создатель (владелец) представления имел привилегии INSERT, UPDATE и DELETE на базовые объекты метаданных.
Предоставить привилегии на представление другим пользователям возможно только если владелец представления сам имеет эти привилегии на базовых объектах. Она будет всегда, если владелец представления является владельцем базовых объектов метаданных.
Пример 4.51. Создание представления
CREATE VIEW ENTRY_LEVEL_JOBS AS
SELECT JOB_CODE, JOB_TITLE
FROM JOB
WHERE MAX_SALARY < 15000;
Пример 4.52. Создание представления с проверкой условия фильтрации
Создание представления возвращающего столбцы JOB_CODE и JOB_TITLE только для тех работ, где MAX_SALARY меньше $15000. При вставке новой записи или изменении существующей будет осуществляться проверка условия MAX_SALARY < 15000, если условие не выполняется, то вставка/изменение будет отвергнуто.
CREATE VIEW ENTRY_LEVEL_JOBS AS
SELECT JOB_CODE, JOB_TITLE
FROM JOB
WHERE MAX_SALARY < 15000
WITH CHECK OPTIONS;
Пример 4.53. Создание представления с использованием списка столбцов
CREATE VIEW PRICE_WITH_MARKUP (
CODE_PRICE,
COST,
COST_WITH_MARKUP
) AS
SELECT
CODE_PRICE,
COST,
COST * 1.1
FROM PRICE;
Пример 4.54. Создание представления с использованием псевдонимов полей
CREATE VIEW PRICE_WITH_MARKUP AS
SELECT
CODE_PRICE,
COST,
COST * 1.1 AS COST_WITH_MARKUP
FROM PRICE;
Пример 4.55. Создание необновляемого представления с использованием хранимой процедуры
CREATE VIEW GOODS_PRICE AS SELECT goods.name AS goodsname, price.cost AS cost, b.quantity AS quantity FROM goods JOIN price ON goods.code_goods = price.code_goods LEFT JOIN sp_get_balance(goods.code_goods) b ON 1 = 1;
Пример 4.56. Создание обновляемого представления с использованием триггеров
-- базовые таблицы RECREATE TABLE t_films(id INT PRIMARY KEY, title VARCHAR(100)); RECREATE TABLE t_sound(id INT PRIMARY KEY, audio BLOB); RECREATE TABLE t_video(id INT PRIMARY KEY, video BLOB); COMMIT; -- создание необновляемого представления RECREATE VIEW v_films AS SELECT f.id, f.title, s.audio, v.video FROM t_films f LEFT JOIN t_sound s ON f.id = s.id LEFT JOIN t_video v ON f.id = v.id; /* Для того чтобы сделать представление обновляемым создадим триггер, который будет производить манипуляции над базовыми таблицами. */ SET TERM ^; CREATE OR ALTER TRIGGER v_films_biud FOR v_films ACTIVE BEFORE INSERT OR UPDATE OR DELETE POSITION 0 AS BEGIN IF (INSERTING) THEN new.id = COALESCE(new.id, GEN_ID(g_films, 1)); IF (NOT DELETING) THEN BEGIN UPDATE OR INSERT INTO t_films(id, title) VALUES(new.id, new.title) MATCHING(id); UPDATE OR INSERT INTO t_sound(id, audio) VALUES(new.id, new.audio) MATCHING(id); UPDATE OR INSERT INTO t_video(id, video) VALUES(new.id, new.video) MATCHING(id); END ELSE BEGIN DELETE FROM t_films WHERE id = old.id; DELETE FROM t_sound WHERE id = old.id; DELETE FROM t_video WHERE id = old.id; END END^ SET TERM ;^ /* Теперь мы можем производить манипуляции над этим представлением как будто мы работаем с таблицей */ INSERT INTO v_films(title, audio, video) VALUES('007 coordinates skyfall', 'pif-paf!', 'oh! waw!');
См. также: ALTER VIEW, CREATE OR ALTER VIEW, RECREATE VIEW, DROP VIEW.
Назначение: Изменение существующего представления.
Доступно в: DSQL.
Синтаксис:
ALTER VIEWviewname
[<full_column_list>
] AS<select_statement>
[WITH CHECK OPTION];<full_column_list>
::= (colname
[,colname
...])
Таблица 4.18. Параметры оператора ALTER VIEW
Параметр | Описание |
---|---|
viewname |
Имя представления. |
select_statement |
Оператор SELECT. |
full_column_list |
Список столбцов представления. |
colname |
Имя столбца представления. Дубликаты имён столбцов не позволяются. |
Оператор ALTER VIEW изменяет определение существующего представления, существующие права на представления и зависимости при этом сохраняются. Синтаксис оператора ALTER VIEW полностью аналогичен синтаксису оператора CREATE VIEW.
Будьте осторожны при изменении количества столбцов представления. Существующий код приложения может стать неработоспособным. Кроме того, PSQL модули, использующие изменённое представление, могут стать некорректными. Информация о том, как это обнаружить, находится в приложении Поле RDB$VALID_BLR.
Только владелец представления и администраторы имеют привилегии на использование ALTER VIEW.
Пример 4.57. Изменение представления
ALTER VIEW PRICE_WITH_MARKUP (
CODE_PRICE,
COST,
COST_WITH_MARKUP
) AS
SELECT
CODE_PRICE,
COST,
COST * 1.15
FROM PRICE;
См. также: CREATE VIEW, CREATE OR ALTER VIEW, RECREATE VIEW.
Назначение: Создание нового или изменение существующего представления.
Доступно в: DSQL.
Синтаксис:
CREATE OR ALTER VIEWviewname
[<full_column_list>
] AS<select_statement>
[WITH CHECK OPTION];<full_column_list>
::= (colname
[,colname
...])
Таблица 4.19. Параметры оператора CREATE OR ALTER VIEW
Параметр | Описание |
---|---|
viewname |
Имя представления. Может содержать до 31 байта. |
select_statement |
Оператор SELECT. |
full_column_list |
Список столбцов представления. |
colname |
Имя столбца представления. Дубликаты имён столбцов не позволяются. |
Оператор CREATE OR ALTER VIEW создаёт представление, если оно не существует. В противном случае он изменит представление с сохранением существующих зависимостей.
Пример 4.58. Создание нового или изменение существующего представления
CREATE OR ALTER VIEW PRICE_WITH_MARKUP (
CODE_PRICE,
COST,
COST_WITH_MARKUP
) AS
SELECT
CODE_PRICE,
COST,
COST * 1.15
FROM PRICE;
См. также: CREATE VIEW, ALTER VIEW, RECREATE VIEW.
Назначение: Удаление существующего представления.
Доступно в: DSQL.
Синтаксис:
DROP VIEW viewname
;
Оператор DROP VIEW удаляет существующее представление. Если представление имеет зависимости, то удаление не будет произведено.
Только владелец представления и администраторы имеют привилегии на использование DROP VIEW.
См. также: CREATE VIEW, RECREATE VIEW.
Назначение: Создание нового или пересоздание существующего представления.
Доступно в: DSQL.
Синтаксис:
RECREATE VIEWviewname
[<full_column_list>
] AS<select_statement>
[WITH CHECK OPTION];<full_column_list>
::= (colname
[,colname
...])
Таблица 4.21. Параметры оператора RECREATE VIEW
Параметр | Описание |
---|---|
viewname |
Имя представления. Может содержать до 31 байта. |
select_statement |
Оператор SELECT. |
full_column_list |
Список столбцов представления. |
colname |
Имя столбца представления. Дубликаты имён столбцов не позволяются. |
Создаёт или пересоздаёт представление. Если представление с таким именем уже существует, то оператор RECREATE VIEW попытается удалить его и создать новое. Оператор RECREATE VIEW не выполнится, если существующее представление имеет зависимости.
Пример 4.60. Создание нового или пересоздание существующего представления
RECREATE VIEW PRICE_WITH_MARKUP (
CODE_PRICE,
COST,
COST_WITH_MARKUP
) AS
SELECT
CODE_PRICE,
COST,
COST * 1.15
FROM PRICE;
См. также: CREATE VIEW, CREATE OR VIEW, DROP VIEW.
Триггер (trigger) — это хранимая процедура особого типа, которая не вызывается непосредственно, а исполнение которой обусловлено наступлением одного из событий, относящегося к одной конкретной таблице (представлению), или наступлению одного из событий базы данных.
Назначение: Создание нового триггера.
Доступно в: DSQL, ESQL.
Синтаксис:
CREATE TRIGGERtrigname
{<relation_trigger_legacy>
|<relation_trigger_sql2003>
|<database_trigger>
} AS [<declarations>
] BEGIN [<PSQL_statements>
] END<relation_trigger_legacy>
::= FOR {tablename
|viewname
} [ACTIVE | INACTIVE] {BEFORE | AFTER}<mutation_list>
[POSITIONnumber
]<relation_trigger_sql2003>
::= [ACTIVE | INACTIVE] {BEFORE | AFTER}<mutation_list>
[POSITIONnumber
] ON {tablename
|viewname
}<database_trigger>
::= [ACTIVE | INACTIVE] ONdb_event
[POSITIONnumber
]<mutation_list>
::=<mutation>
[OR<mutation>
[OR<mutation>
]]<mutation>
::= { INSERT | UPDATE | DELETE }<db_event>
::= { CONNECT | DISCONNECT | TRANSACTION START | TRANSACTION COMMIT | TRANSACTION ROLLBACK }
Таблица 4.22. Параметры оператора CREATE TRIGGER
Параметр | Описание |
---|---|
trigname |
Имя триггера. Может содержать до 31 байта. |
relation_trigger_legacy |
Объявление табличного триггера (унаследованное). |
relation_trigger_sql2003 |
Объявление табличного триггера согласно стандарту SQL-2003. |
database_trigger |
Объявление триггера базы данных. |
tablename |
Имя таблицы. |
viewname |
Имя представления. |
mutation_list |
Список событий таблицы. |
mutation |
Одно из событий таблицы. |
db_event |
Событие соединения или транзакции. |
number |
Порядок срабатывания триггера. От 0 до 32767. |
declarations |
Секция объявления локальных переменных и именованных курсоров. |
PSQL_statments |
Операторы языка PSQL. |
Оператор CREATE TRIGGER создаёт новый триггер. Триггер может быть создан для события (или событий) отношения (таблицы или представления) или для одного из событий базы данных.
Оператор CREATE TRIGGER как и его родственники ALTER TRIGGER, CREATE OR ALTER TRIGGER и RECREATE TRIGGER являются составными операторами, содержащими заголовок и тело.
Заголовок определяет имя триггера, а также содержит имя отношения (для табличных триггеров), фазу триггера, событие (или события) на которые срабатывает триггер и позицию. Имя триггера должно быть уникальным среди имён других триггеров.
Тело триггера состоит из необязательных объявлений локальных переменных и именованных курсоров, и одного или нескольких операторов или блоков операторов, заключённых во внешнем блоке, который начинается с ключевого слова BEGIN и заканчивается ключевым словом END. Объявления и внутренние операторы завершаются точкой с запятой (;).
Некоторые редакторы SQL-операторов — в частности утилита isql, которая идёт в комплекте с Firebird, и возможно некоторые сторонние редакторы — используют внутреннее соглашение, которое требует, чтобы все операторы были завершены с точкой с запятой.
Это создает конфликт с синтаксисом PSQL при кодировании в этих средах. Если вы не знакомы с этой проблемой и её решением, пожалуйста, изучите детали в главе PSQL в разделе, озаглавленном Изменение терминатора в isql.
DML триггеры выполняются на уровне строки (записи) каждый раз, когда изменяется образ строки. Они могут быть определены и для таблиц и представлений.
Объявление DML триггера существует в двух вариантах:
своеобразная, унаследованная форма;
SQL-2003 совместимая (рекомендуемая).
В настоящее время рекомендуется использовать SQL-2003 совместимую форму.
Для DML триггера обязательно указывается фаза и одно или несколько событий.
Триггер может быть в одном из двух состояний активном (ACTIVE) или неактивном (INACTIVE). Запускаются только активные триггеры. По умолчанию триггеры создаются в активном состоянии.
Триггер может выполняться в одной из двух фаз, связанных с запрошенными изменениями состояния данных. Ключевое слово BEFORE означает, что триггер вызывается до наступления соответствующего события (событий, если их указано несколько), AFTER — после наступления события (событий).
Для DML триггера может быть указано одно из событий таблицы (представления) — INSERT (добавление), UPDATE (изменение), DELETE (удаление) — или несколько событий, разделённых ключевым словом OR, при которых вызывается триггер. При создании триггера каждое событие (INSERT, UPDATE или DELETE) не должно упоминаться более одного раза.
Контекстные переменные INSERTING, UPDATING и DELETING логического типа могут быть использованы в теле триггера для определения события, которое вызвало срабатывание триггера.
Ключевое слово POSITION позволяет задать порядок, в котором будут выполняться триггеры с одинаковой фазой и событием (или группы событий). По умолчанию позиция равна 0. Если позиции для триггеров не заданы или несколько триггеров имеют одно и то же значение позиции, то такие триггеры будут выполняться в алфавитном порядке их имен.
Тело триггера может содержать объявления локальных переменных и курсоров. Подробности вы можете посмотреть в главе «Процедурный язык PSQL» в разделах DECLARE VARIABLE и DECLARE CURSOR.
После секции объявления следует основной блок BEGIN ... END, в который заключается PSQL код триггера. В этом блоке могут содержаться DML и PSQL операторы, а также вложенные BEGIN ... END блоки. Любой из BEGIN ... END блоков может быть пустым, в том числе и главный блок.
Только владелец таблицы (представления) для которой создаётся DML триггер и администраторы имеют привилегии на использование CREATE TRIGGER.
Пример 4.61. Создание DML триггера в Legacy стиле
CREATE TRIGGER SET_CUST_NO FOR CUSTOMER ACTIVE BEFORE INSERT POSITION 0 AS BEGIN IF (NEW.CUST_NO IS NULL) THEN NEW.CUST_NO = GEN_ID(CUST_NO_GEN, 1); END
Пример 4.62. Создание DML триггера согласно стандарту SQL-2003
CREATE TRIGGER set_cust_no ACTIVE BEFORE INSERT POSITION 0 ON customer AS BEGIN IF (NEW.cust_no IS NULL) THEN NEW.cust_no = GEN_ID(cust_no_gen, 1); END
Пример 4.63. Создание DML триггера на несколько событий
CREATE TRIGGER TR_CUST_LOG ACTIVE AFTER INSERT OR UPDATE OR DELETE POSITION 10 ON CUSTOMER AS BEGIN INSERT INTO CHANGE_LOG (LOG_ID, ID_TABLE, TABLE_NAME, MUTATION) VALUES (NEXT VALUE FOR SEQ_CHANGE_LOG, OLD.CUST_NO, 'CUSTOMER', CASE WHEN INSERTING THEN 'INSERT' WHEN UPDATING THEN 'UPDATE' WHEN DELETING THEN 'DELETE' END); END
См. также: ALTER TRIGGER, DROP TRIGGER.
Триггер может быть создан для одного из событий базы данных:
CONNECT (соединение с базой данных);
DISCONNECT (отсоединение от базы данных);
TRANSACTION START (старт транзакции);
TRANSACTION COMMIT (подтверждение транзакции);
TRANSACTION ROLLBACK (откат транзакции).
Указать для триггера несколько событий базы данных невозможно.
Триггеры на события CONNECT и DISCONNECT выполняются в специально созданной для этого транзакции. Если при обработке триггера не было вызвано исключение, то транзакция подтверждается. Не перехваченные исключения откатят транзакцию и:
в случае триггера на событие CONNECT соединение разрывается, а исключения возвращается клиенту;
для триггера на событие DISCONNECT соединение разрывается, как это и предусмотрено, но исключения не возвращается клиенту.
Триггеры на события транзакций срабатывают при старте транзакции, её подтверждении или откате. Не перехваченные исключения обрабатываются в зависимости от типа события:
для события TRANSACTION START исключение возвращается клиенту, а транзакция отменяется;
для события TRANSACTION COMMIT исключение возвращается клиенту, действия, выполненные триггером, и транзакция отменяются;
для события TRANSACTION ROLLBACK исключение не возвращается клиенту, а транзакция, как и предусмотрено, отменяется.
Из вышеизложенного следует, что нет прямого способа узнать, какой триггер (DISCONNECT или ROLLBACK) вызвал исключение. Также ясно, что вы не сможете подключиться к базе данных в случае исключения в триггере на событие CONNECT, а также отменяется старт транзакции при исключении в триггере на событие TRANSACTION START. В обоих случаях база данных эффективно блокируется до тех пор, пока вы не отключите триггеры базы данных и не исправите ошибочный код.
В случае двухфазных транзакций триггеры на событие TRANSACTION START срабатывают в фазе подготовки (prepare), а не в фазе commit.
Триггеры для событий базы данных DISCONNECT и ROLLBACK не будут вызваны при отключении клиентов через таблицы мониторинга (DELETE FROM MON$ATTACHMENTS).
Использование оператора IN AUTONOMOUS TRANSACTION DO в триггерах на событие базы данных связанные с транзакциями (COMMIT, ROLLBACK, START) может привести к его зацикливанию.
Только владелец базы данных и администраторы имеют привилегии на создания триггеров для событий базы данных.
Пример 4.64. Создание триггера на событие подключения к БД для логирования события
CREATE TRIGGER tr_log_connect
INACTIVE ON CONNECT POSITION 0
AS
BEGIN
INSERT INTO LOG_CONNECT (ID,
USERNAME,
ATIME)
VALUES (NEXT VALUE FOR SEQ_LOG_CONNECT,
CURRENT_USER,
CURRENT_TIMESTAMP);
END
Пример 4.65. Создание триггера на событие подключения к БД для контроля доступа
CREATE EXCEPTION E_INCORRECT_WORKTIME 'Рабочий день ещё не начался'; CREATE TRIGGER TR_LIMIT_WORKTIME ACTIVE ON CONNECT POSITION 1 AS BEGIN IF ((CURRENT_USER <> 'SYSDBA') AND NOT (CURRENT_TIME BETWEEN time '9:00' AND time '17:00')) THEN EXCEPTION E_INCORRECT_WORKTIME; END
См. также: ALTER TRIGGER, DROP TRIGGER.
Назначение: Изменение существующего триггера.
Доступно в: DSQL, ESQL.
Синтаксис:
ALTER TRIGGERtrigname
{ [ACTIVE | INACTIVE] [{BEFORE | AFTER}<mutation_list>
] [POSITIONnumber
] [ AS [<declarations>
] BEGIN [<PSQL_statements>
] END ]<mutation_list>
::=<mutation>
[OR<mutation>
[OR<mutation>
]]<mutation>
::= { INSERT | UPDATE | DELETE }
Таблица 4.23. Параметры оператора ALTER TRIGGER
Параметр | Описание |
---|---|
trigname |
Имя триггера. |
mutation_list |
Список событий таблицы. |
mutation |
Одно из событий таблицы. |
number |
Порядок срабатывания триггера. От 0 до 32767. |
declarations |
Секция объявления локальных переменных и именованных курсоров. |
PSQL_statments |
Операторы языка PSQL. |
Оператор ALTER TRIGGER позволяет изменять заголовок и/или тело триггера.
В операторе изменения триггера можно изменить:
Состояние активности (ACTIVE | INACTIVE);
Фазу (BEFORE | AFTER);
Событие(я);
Позицию срабатывания;
Код тела триггера.
Если какой-либо элемент не указан, то он остаётся без изменений.
DML триггер невозможно изменить в триггер на событие базы данных и наоборот.
Событие в триггере базы данных невозможно изменить.
Триггер с ключевым словом BEFORE наступает до соответствующего события, с ключевым словом AFTER — после соответствующего события.
Один DML триггер может содержать более одного события (INSERT, UPDATE, DELETE). События должны быть разделены ключевым словом OR. Каждое из событий может быть указано не более одного раза.
Ключевое слово POSITION позволяет задать дополнительный порядок выполнения с одинаковыми фазой и событием. По умолчанию позиция равна 0. Если позиция не задана, или если несколько триггеров имеют один и тот же номер позиции, то триггеры будут выполнены в алфавитном порядке их наименований.
Только администраторы и следующие пользователи имеют привилегии на использование ALTER TRIGGER:
Владелец таблицы или представления (для DML триггеров);
Владелец базы данных (для триггеров на событие базы данных).
Пример 4.66. Отключение (перевод в неактивное состояние) триггера
ALTER TRIGGER set_cust_no INACTIVE;
Пример 4.68. Перевод триггера в неактивное состояние и изменение списка событий
ALTER TRIGGER TR_CUST_LOG INACTIVE AFTER INSERT OR UPDATE;
Пример 4.69. Перевод триггера в активное состояние, изменение его позиции и его тела
ALTER TRIGGER tr_log_connect
ACTIVE POSITION 1
AS
BEGIN
INSERT INTO LOG_CONNECT (ID,
USERNAME,
ROLENAME,
ATIME)
VALUES (NEXT VALUE FOR SEQ_LOG_CONNECT,
CURRENT_USER,
CURRENT_ROLE,
CURRENT_TIMESTAMP);
END
См. также: CREATE TRIGGER, CREATE OR ALTER TRIGGER, RECREATE TRIGGER.
Назначение: Создание нового или изменение существующего триггера.
Доступно в: DSQL, ESQL.
Синтаксис:
CREATE OR ALTER TRIGGERtrigname
{<relation_trigger_legacy>
|<relation_trigger_sql2003>
|<database_trigger>
} AS [<declarations>
] BEGIN [<PSQL_statements>
] END
Полное описание оператора см. CREATE TRIGGER.
Оператор CREATE OR ALTER TRIGGER создаёт новый триггер, если он не существует, или изменяет и перекомпилирует его в противном случае, при этом существующие права и зависимости сохраняются.
Пример 4.70. Создание нового или изменение существующего триггера
CREATE OR ALTER TRIGGER set_cust_no ACTIVE BEFORE INSERT POSITION 0 ON customer AS BEGIN IF (NEW.cust_no IS NULL) THEN NEW.cust_no = GEN_ID(cust_no_gen, 1); END
См. также: CREATE TRIGGER, ALTER TRIGGER, RECREATE TRIGGER.
Назначение: Удаление существующего триггера.
Доступно в: DSQL, ESQL.
Синтаксис:
DROP TRIGGER trigname
Оператор DROP TRIGGER удаляет существующий триггер.
Только администраторы и следующие пользователи имеют привилегии на использование DROP TRIGGER:
Владелец таблицы или представления (для DML триггеров);
Владелец базы данных (для триггеров на событие базы данных).
См. также: CREATE TRIGGER, ALTER TRIGGER.
Назначение: Создание нового или пересоздание существующего триггера.
Доступно в: DSQL, ESQL.
Синтаксис:
RECREATE TRIGGERtrigname
{<relation_trigger_legacy>
|<relation_trigger_sql2003>
|<database_trigger>
} AS [<declarations>
] BEGIN [<PSQL_statements>
] END
Полное описание оператора см. CREATE TRIGGER.
Оператор RECREATE TRIGGER создаёт новый триггер, если триггер с указанным именем не существует, в противном случае оператор RECREATE TRIGGER попытается удалить его и создать новый.
Пример 4.72. Создание или пересоздание триггера
RECREATE TRIGGER set_cust_no ACTIVE BEFORE INSERT POSITION 0 ON customer AS BEGIN IF (NEW.cust_no IS NULL) THEN NEW.cust_no = GEN_ID(cust_no_gen, 1); END
См. также: CREATE TRIGGER, DROP TRIGGER, CREATE OR ALTER TRIGGER.
Хранимая процедура (ХП) — это программный модуль, который может быть вызван с клиента, из другой процедуры, функции, выполнимого блока (executable block) или триггера. Хранимые процедуры, хранимые функции, исполняемые блоки и триггеры пишутся на процедурном языке SQL (PSQL). Большинство операторов SQL доступно и в PSQL, иногда с ограничениями или расширениями. Заметными исключениями являются DDL и операторы управления транзакциями.
Хранимые процедуры могут принимать и возвращать множество параметров.
Назначение: Создание новой хранимой функции.
Доступно в: DSQL, ESQL.
Синтаксис:
CREATE PROCEDUREprocname
[(<inparam>
[,<inparam>
...])] RETURNS (<outparam>
[,<outparam>
...]) AS [<declarations>
] BEGIN [<PSQL_statements>
] END<inparam>
::=<param_decl>
[{= | DEFAULT}<value>
]<outparam>
::=<param_decl>
<value>
::= {literal
| NULL |context_var
}<param_decl>
::=paramname
<type>
[NOT NULL] [COLLATEcollation
]<type>
::=<datatype>
| [TYPE OF]domain
| TYPE OF COLUMNrel
.col
<datatype>
::= {SMALLINT | INT[EGER] | BIGINT} | {FLOAT | DOUBLE PRECISION} | {DATE | TIME | TIMESTAMP} | {DECIMAL | NUMERIC} [(precision
[,scale
])] | {CHAR | CHARACTER | CHARACTER VARYING | VARCHAR} [(size
)] [CHARACTER SETcharset
] | {NCHAR | NATIONAL CHARACTER | NATIONAL CHAR} [VARYING] [(size
)] | BLOB [SUB_TYPE {subtype_num
|subtype_name
}] [SEGMENT SIZEseglen
] [CHARACTER SETcharset
] | BLOB [(seglen
[,subtype_num
])]<declarations>
::=<declare_item>
[<declare_item>
...]<declare_item>
::=<declare_var>
; |<declare_cursor>
;
Таблица 4.25. Параметры оператора CREATE PROCEDURE
Параметр | Описание |
---|---|
procname |
Имя хранимой процедуры. Может содержать до 31 байта. |
inparam |
Описание входного параметра. |
outparam |
Описание выходного параметра. |
declarations |
Секция объявления локальных переменных, именованных курсоров, подпроцедур и подфункций. |
declare_var |
Объявление локальной переменной. |
declare_cursor |
Объявление именованного курсора. |
literal |
Литерал, совместимый по типу с параметром. |
context_var |
Любая контекстная переменная, тип которой совместим с типом параметра. |
paramname |
Имя входного или выходного параметра процедуры. Может содержать до 31 байта. Имя параметра должно быть уникальным среди входных и выходных параметров процедуры, а также её локальных переменных. |
datatype |
Тип данных SQL. |
collation |
Порядок сортировки. |
domain |
Домен. |
rel |
Имя таблицы или представления. |
col |
Имя столбца таблицы или представления. |
precision |
Общее количество значащих цифр, которое способен сохранить параметр (от 1 до 18). |
scale |
Количество цифр после десятичной точки. От 0 до 18, должно быть меньше
или равно |
size |
Максимальный размер строки в символах. |
charset |
Набор символов. |
subtype_num |
Номер подтипа BLOB. См. Подтипы BLOB. |
subtype_name |
Мнемоника подтипа BLOB. См. Подтипы BLOB. |
seqlen |
Размер сегмента, не может превышать 65535. |
Оператор CREATE PROCEDURE создаёт новую хранимую процедуру. Имя хранимой процедуры должно быть уникальным среди имён всех хранимых процедур, таблиц и представлений базы данных.
CREATE PROCEDURE является составным оператором, состоящий из заголовка и тела.
Заголовок определяет имя хранимой процедуры и объявляет входные и выходные параметры, если они должны быть возвращены процедурой.
Тело процедуры состоит из необязательных объявлений локальных переменных и именованных курсоров, и одного или нескольких операторов, или блоков операторов, заключённых во внешнем блоке, который начинается с ключевого слова BEGIN, и завершается ключевым словом END. Объявления локальных переменных и именованных курсоров, а также внутренние операторы должны завершаться точкой с запятой (;).
Некоторые редакторы SQL-операторов — в частности утилита isql, которая идёт в комплекте с Firebird, и возможно некоторые сторонние редакторы — используют внутреннее соглашение, которое требует, чтобы все операторы были завершены с точкой с запятой.
Это создает конфликт с синтаксисом PSQL при кодировании в этих средах. Если вы не знакомы с этой проблемой и её решением, пожалуйста, изучите детали в главе PSQL в разделе, озаглавленном Изменение терминатора в isql.
У каждого параметра указывается тип данных. Кроме того, для параметра можно указать ограничение NOT NULL, тем самым запретив передавать в него значение NULL.
Для параметра строкового типа существует возможность задать порядок сортировки с помощью предложения COLLATE.
Входные параметры заключаются в скобки после имени хранимой процедуры. Они передаются в процедуру по значению, то есть любые изменения входных параметров внутри процедуры никак не повлияет на значения этих параметров в вызывающей программе.
Входные параметры могут иметь значение по умолчанию. Параметры, для которых заданы значения, должны располагаться в конце списка параметров.
Необязательное предложение RETURNS позволяет задать список выходных параметров хранимой процедуры.
В качестве типа параметра можно указать имя домена. В этом случае, параметр будет наследовать все характеристики домена.
Если перед названием домена дополнительно используется предложение "TYPE OF", то используется только тип данных домена — не проверяется (не используется) его ограничение (если оно есть в домене) на NOT NULL, CHECK ограничения и/или значения по умолчанию. Если домен текстового типа, то всегда используется его набор символов и порядок сортировки.
Входные и выходные параметры можно объявлять, используя тип данных столбцов существующих таблиц и представлений. Для этого используется предложение TYPE OF COLUMN, после которого указывается имя таблицы или представления и через точку имя столбца.
При использовании TYPE OF COLUMN наследуется только тип данных, а в случае строковых типов ещё и набор символов, и параметры сортировки. Ограничения и значения по умолчанию столбца никогда не используются.
Для входных параметров, параметры сортировки, которые наследуются вместе с типом столбца игнорируются при сравнении (например проверки на равенство). Для локальных переменных, поведение отличается.
Ошибка исправлена в Firebird 3.
В необязательной секции declarations
описаны локальные
переменные процедуры и именованные курсоры. Локальные переменные подчиняются тем же
правилам что и входные и выходные параметры процедуры в отношении спецификации типа
данных. Подробности вы можете посмотреть в главе «Процедурный язык PSQL» в
разделах DECLARE VARIABLE и DECLARE CURSOR.
После заголовка следует тело хранимой процедуры, состоящее из одного или нескольких PSQL операторов, заключенных между ключевыми словами BEGIN и END. Внутри тела процедуры может быть множество BEGIN...END блоков, представляющих собой законченный оператор.
Создать новую хранимую процедуру может любой пользователь, подключенный к базе данных. Пользователь, создавший хранимую процедуру, становится её владельцем.
Пример 4.73. Создание хранимой процедуры
CREATE PROCEDURE ADD_BREED ( NAME D_BREEDNAME, /* Наследуются характеристики домена */ NAME_EN TYPE OF D_BREEDNAME, /* Наследуется только тип домена */ SHORTNAME TYPE OF COLUMN BREED.SHORTNAME, /* Наследуется тип столбца таблицы */ REMARK VARCHAR(120) CHARACTER SET WIN1251 COLLATE PXW_CYRL, CODE_ANIMAL INT NOT NULL DEFAULT 1 ) RETURNS ( CODE_BREED INT ) AS BEGIN INSERT INTO BREED ( CODE_ANIMAL, NAME, NAME_EN, SHORTNAME, REMARK) VALUES ( :CODE_ANIMAL, :NAME, :NAME_EN, :SHORTNAME, :REMARK) RETURNING CODE_BREED INTO CODE_BREED; END
См. также: CREATE OR ALTER PROCEDURE, ALTER PROCEDURE, RECREATE PROCEDURE, DROP PROCEDURE.
Назначение: Изменение существующей хранимой процедуры.
Доступно в: DSQL, ESQL.
Синтаксис:
ALTER PROCEDUREprocname
[(<inparam>
[,<inparam>
...])] RETURNS (<outparam>
[,<outparam>
...]) AS [<declarations>
] BEGIN [<PSQL_statements>
] END<inparam>
::=<param_decl>
[{= | DEFAULT}<value>
]<outparam>
::=<param_decl>
<value>
::= {literal
| NULL |context_var
}<param_decl>
::=paramname
<type>
[NOT NULL] [COLLATEcollation
]<type>
::=<datatype>
| [TYPE OF]domain
| TYPE OF COLUMNrel
.col
<datatype>
::= {SMALLINT | INT[EGER] | BIGINT} | {FLOAT | DOUBLE PRECISION} | {DATE | TIME | TIMESTAMP} | {DECIMAL | NUMERIC} [(precision
[,scale
])] | {CHAR | CHARACTER | CHARACTER VARYING | VARCHAR} [(size
)] [CHARACTER SETcharset
] | {NCHAR | NATIONAL CHARACTER | NATIONAL CHAR} [VARYING] [(size
)] | BLOB [SUB_TYPE {subtype_num
|subtype_name
}] [SEGMENT SIZEseglen
] [CHARACTER SETcharset
] | BLOB [(seglen
[,subtype_num
])]<declarations>
::=<declare_item>
[<declare_item>
...]<declare_item>
::=<declare_var>
; |<declare_cursor>
;
Таблица 4.26. Параметры оператора ALTER PROCEDURE
Параметр | Описание |
---|---|
procname |
Имя существующей хранимой процедуры |
inparam |
Описание входного параметра. |
outparam |
Описание выходного параметра. |
declarations |
Секция объявления локальных переменных, именованных курсоров, подпроцедур и подфункций. |
declare_var |
Объявление локальной переменной. |
declare_cursor |
Объявление именованного курсора. |
literal |
Литерал, совместимый по типу с параметром. |
context_var |
Любая контекстная переменная, тип которой совместим с типом параметра. |
paramname |
Имя входного или выходного параметра процедуры. Может содержать до 31 байта. Имя параметра должно быть уникальным среди входных и выходных параметров процедуры, а также её локальных переменных. |
datatype |
Тип данных SQL. |
collation |
Порядок сортировки. |
domain |
Домен. |
rel |
Имя таблицы или представления. |
col |
Имя столбца таблицы или представления. |
precision |
Общее количество значащих цифр, которое способен сохранить параметр (от 1 до 18). |
scale |
Количество цифр после десятичной точки. От 0 до 18, должно быть меньше
или равно |
size |
Максимальный размер строки в символах. |
charset |
Набор символов. |
subtype_num |
Номер подтипа BLOB. См. Подтипы BLOB. |
subtype_name |
Мнемоника подтипа BLOB. См. Подтипы BLOB. |
seqlen |
Размер сегмента, не может превышать 65535. |
Оператор ALTER PROCEDURE позволяет изменять состав и характеристики входных и выходных параметров, локальных переменных, именованных курсоров и тело хранимой процедуры. После выполнения существующие привилегии и зависимости сохраняются.
Будьте осторожны при изменении количества и типов входных и выходных параметров хранимых процедур. Существующий код приложения может стать неработоспособным из-за того, что формат вызова процедуры несовместим с новым описанием параметров. Кроме того, PSQL модули, использующие изменённую хранимую процедуру, могут стать некорректными. Информация о том, как это обнаружить, находится в приложении Поле RDB$VALID_BLR.
Только владелец хранимой процедуры и администраторы имеют привилегии на использование ALTER PROCEDURE.
Пример 4.74. Изменение хранимой процедуры
ALTER PROCEDURE GET_EMP_PROJ (
EMP_NO SMALLINT)
RETURNS (
PROJ_ID VARCHAR(20))
AS
BEGIN
FOR SELECT
PROJ_ID
FROM
EMPLOYEE_PROJECT
WHERE
EMP_NO = :emp_no
INTO :proj_id
DO
SUSPEND;
END
См. также: CREATE PROCEDURE, CREATE OR ALTER PROCEDURE, RECREATE PROCEDURE, DROP PROCEDURE.
Назначение: Создание новой или изменение существующей хранимой процедуры.
Доступно в: DSQL, ESQL.
Синтаксис:
CREATE OR ALTER PROCEDUREprocname
[(<inparam>
[,<inparam>
...])] RETURNS (<outparam>
[,<outparam>
...]) AS [<declarations>
] BEGIN [<PSQL_statements>
] END
Подробнее см. CREATE PROCEDURE.
Оператор CREATE OR ALTER PROCEDURE создаёт новую или изменяет существующую хранимую процедуру. Если хранимая процедура не существует, то она будет создана с использованием предложения CREATE PROCEDURE. Если она уже существует, то она будет изменена и откомпилирована, при этом существующие привилегии и зависимости сохраняются.
Пример 4.75. Создание или изменение хранимой процедуры
CREATE OR ALTER PROCEDURE GET_EMP_PROJ (
EMP_NO SMALLINT)
RETURNS (
PROJ_ID VARCHAR(20))
AS
BEGIN
FOR SELECT
PROJ_ID
FROM
EMPLOYEE_PROJECT
WHERE
EMP_NO = :emp_no
INTO :proj_id
DO
SUSPEND;
END
См. также: CREATE PROCEDURE, ALTER PROCEDURE, RECREATE PROCEDURE, DROP PROCEDURE.
Назначение: Удаление существующей хранимой процедуры.
Доступно в: DSQL, ESQL.
Синтаксис:
DROP PROCEDURE procname
Оператор DROP PROCEDURE удаляет существующую хранимую процедуру. Если от хранимой процедуры существуют зависимости, то при попытке удаления такой процедуру будет выдана соответствующая ошибка.
Только владелец хранимой процедуры и администраторы имеют привилегии на использование DROP PROCEDURE.
См. также: CREATE PROCEDURE, RECREATE PROCEDURE.
Назначение: Создание новой или пересоздание существующей хранимой процедуры.
Доступно в: DSQL, ESQL.
Синтаксис:
RECREATE PROCEDUREprocname
[(<inparam>
[,<inparam>
...])] RETURNS (<outparam>
[,<outparam>
...]) AS [<declarations>
] BEGIN [<PSQL_statements>
] END
Подробнее см. CREATE PROCEDURE.
Оператор RECREATE PROCEDURE создаёт новую или пересоздаёт существующую хранимую процедуру. Если процедура с таким именем уже существует, то оператор попытается удалить её и создать новую процедуру. Операция закончится неудачей при подтверждении транзакции, если процедура имеет зависимости.
Имейте ввиду, что ошибки зависимостей не обнаруживаются до фазы подтверждения транзакции.
Пример 4.77. Создание новой или пересоздание существующей хранимой процедуры
RECREATE PROCEDURE GET_EMP_PROJ (
EMP_NO SMALLINT)
RETURNS (
PROJ_ID VARCHAR(20))
AS
BEGIN
FOR SELECT
PROJ_ID
FROM
EMPLOYEE_PROJECT
WHERE
EMP_NO = :emp_no
INTO :proj_id
DO
SUSPEND;
END
См. также: CREATE PROCEDURE, CREATE OR ALTER PROCEDURE, DROP PROCEDURE.
Внешние функции, также известные как функции определяемые пользователем (User Defined Function) — это программы, написанные на любом языке программирования, и хранящиеся в динамических библиотеках. После того как функция объявлена в базе данных, она становится в динамических и процедурных операторах, как будто они реализованы внутри языка SQL.
Внешние функции существенно расширяют возможности SQL по обработке данных. Для того чтобы функции были доступны в базе данных, их необходимо объявить с помощью оператора DECLARE EXTERNAL FUNCTON.
После объявления функции, содержащая её библиотека будет загружаться при первом обращении к любой из функций, включённой в библиотеку.
Назначение: Объявление в базе данных функции определённой пользователем (UDF).
Доступно в: DSQL, ESQL.
Синтаксис:
DECLARE EXTERNAL FUNCTIONfuncname
[<arg_type_decl>
[,<arg_type_decl>
...]] RETURNS {sqltype
[BY {DESCRIPTOR | VALUE}] | CSTRING(length
) | PARAMETERparam_num
} [FREE_IT] ENTRY_POINT 'entry_point
' MODULE_NAME 'library_name
';<arg_type_decl>
::=sqltype
[{BY DESCRIPTOR} | {BY SCALAR_ARRAY} | NULL] | CSTRING(length
) [NULL]
Таблица 4.28. Параметры оператора DECLARE EXTERNAL FUNCTION
Параметр | Описание |
---|---|
funcname |
Имя внешней функции. Может содержать до 31 байта. |
entry_point |
Имя экспортируемой функции (точка входа). |
library_name |
Имя модуля, в котором расположена функция. |
sqltype |
Тип данных SQL. Не может быть массивом или элементом массива. |
length |
Максимальная длина нуль терминальной строки. Указывается в байтах. |
param_num |
Номер входного параметра, который будет возвращён функцией. |
Оператор DECLARE EXTERNAL FUNCTION делает доступным функцию, определенную пользователем (UDF), в базе данных. Внешние функции должны быть объявлены в каждой базе данных, которая собирается их использовать. Не нужно объявлять UDF, если вы никогда не будете её использовать.
Имя внешней функции должно быть уникальным среди всех имён функций. Оно может отличаться от имени функции указанной в аргументе ENTRY_POINT.
Входные параметры функции перечисляются через запятую сразу после имени функции. Для
каждого параметра указывается SQL тип данных. Массивы не могут использоваться в качестве
параметров функций. Помимо SQL типов можно указать тип CSTRING. В этом случае параметр
является нуль терминальной строкой с максимальной длиной length
байт. Существует несколько механизмов передачи параметра из движка Firebird во внешню
функцию, каждый из этих механизмов будет расмотрен отдельно.
По умолчанию входные параметры передаются по ссылке. Не существует отдельного предложения для явного указания, что параметр передаётся по ссылке.
При передаче NULL значения по ссылке оно преобразуется в эквивалент нуля, например, число 0 или пустую строку. Если после указанного параметра указано ключевое слово NULL, то при передаче значение NULL оно попадёт в функцию в виде нулевого указателя (NULL).
Обратите внимание на то, что объявление функции с ключевым словом NULL не гарантирует вам, что эта функция правильно обработает входной параметр со значением NULL. Любая функция должна быть написана или переписана таким образом, чтобы правильно обрабатывать значения NULL. Всегда смотрите и используйте объявления функции, предоставленные её разработчиком.
Если указано предложение BY DESCRIPTOR, то входной параметр передаётся по дескриптору. В этом случае параметр UDF получит указатель на внутреннюю структуру, известную как дескриптор, несущую информацию о типе данных, подтипе, точности, наборе символов и сортировке, масштабе, указателе на сами данные и некоторых флагах, которых фалгов, в том числе NULL индикаторе. Отметим, что это объявление работает только в том случае, если внешняя функция написана с использованием дескриптора.
При передаче параметра функции по дескриптору передаваемое значение не приводится к задекларированному типу данных.
Предложение BY SCALAR_ARRAY используетеся при передачи массивов в качестве входных параметров. В отличие от других типов, вы не можете вернуть массив из UDF.
Обязательное предложение RETURNS описывает выходной параметр возвращаемый функцией. Функция всегда возвращает только один параметр. Выходной параметр может быть любым SQL типом (кроме массива и элемента массива) или нуль терминальной строкой (CSTRING). Выходной параметр может быть передан по ссылке, по дескриптору или по значению. По умолчанию выходной параметр передаётся по ссылке. Если указано предложение BY DESCRIPTOR, то выходной параметр передаётся по дескриптору. Если указано предложение BY VALUE, то выходной параметр передаётся по значению.
Ключевое слово PARAMETER указывает, что функция возвращает значение из параметра с
номером param_num
. Такая необходимость возникает, если необходимо
возвращать значение типа BLOB.
Ключевое слово FREE_IT означает, что память, выделенная для хранения возвращаемого значения, будет освобождена после завершения выполнения функции. Применяется только в том случае, если эта память в UDF выделялась динамически. В такой UDF память должна выделяться при помощи функции ib_util_malloc из модуля ib_util. Это необходимо для совместимости функций выделения и освобождения памяти используемого в коде Firebird и коде UDF.
Предложение ENTRY_POINT указывает имя точки входа (имя экспортируемой функции) в модуле.
Предложение MODULE_NAME задаёт имя модуля, в котором находится экспортируемая функция. В
ссылке на модуль может отсутствовать полный путь и расширение файла. Это позволяет легче
переносить базу данных между различными платформами. По умолчанию динамические библиотеки
пользовательских функций должны располагаться в папке UDF корневого каталога сервера.
Параметр UDFAccess
в файле firebird.conf
позволяет изменить ограничения доступа к библиотекам внешних функций.
Объявить внешнюю функцию (UDF) может любой пользователь, подключенный к базе данных.
Пример 4.78. Объявление внешней функции с передачей входных и выходных параметров по ссылке
DECLARE EXTERNAL FUNCTION addDay TIMESTAMP, INT RETURNS TIMESTAMP ENTRY_POINT 'addDay' MODULE_NAME 'fbudf';
Пример 4.79. Объявление внешней функции с передачей входных и выходных параметров по дескриптору
DECLARE EXTERNAL FUNCTION invl INT BY DESCRIPTOR, INT BY DESCRIPTOR RETURNS INT BY DESCRIPTOR ENTRY_POINT 'idNvl' MODULE_NAME 'fbudf';
Пример 4.80. Объявление внешней функции с передачей входных параметров по ссылке, выходных по значению
DECLARE EXTERNAL FUNCTION isLeapYear TIMESTAMP RETURNS INT BY VALUE ENTRY_POINT 'isLeapYear' MODULE_NAME 'fbudf';
Пример 4.81. Объявление внешней функции с передачей входных и выходных параметров по дескриптору. В качестве выходного параметра используется второй параметр функции.
DECLARE EXTERNAL FUNCTION i64Truncate NUMERIC(18) BY DESCRIPTOR, NUMERIC(18) BY DESCRIPTOR RETURNS PARAMETER 2 ENTRY_POINT 'fbtruncate' MODULE_NAME 'fbudf';
См. также: ALTER EXTERNAL FUNCTION, DROP EXTERNAL FUNCTION.
Назначение: Изменение точки входа и/или имени модуля для функции определённой пользователем (UDF).
Доступно в: DSQL.
Синтаксис:
ALTER EXTERNAL FUNCTIONfuncname
[ENTRY_POINT 'new_entry_point
'] [MODULE_NAME 'new_library_name
'];
Таблица 4.29. Параметры оператора ALTER EXTERNAL FUNCTION
Параметр | Описание |
---|---|
funcname |
Имя внешней функции. |
new_entry_point |
Новое имя экспортируемой функции (точки входа). |
new_library_name |
Новое имя модуля, в котором расположена функция. |
Оператор ALTER EXTERNAL FUNCTION изменяет точку вход и/или имя модуля для функции определённой пользователем (UDF). При этом существующие зависимости сохраняются.
Предложение ENTRY_POINT позволяет указать новую точку входа (имя экспортируемой функции).
Предложение MODULE_NAME позволяет указать новое имя модуля, в котором расположена экспортируемая функция.
Изменить точку входа и имя модуля может любой пользователь, подключенный к базе данных.
Пример 4.82. Изменение точки входа для внешней функции
ALTER EXTERNAL FUNCTION invl ENTRY_POINT 'intNvl';
Пример 4.83. Изменение имени модуля для внешней функции
ALTER EXTERNAL FUNCTION invl MODULE_NAME 'fbudf2';
См. также: DECLARE EXTERNAL FUNCTION, DROP EXTERNAL FUNCTION.
Назначение: Удаление объявления функции определённой пользователем (UDF) из базы данных.
Доступно в: DSQL, ESQL.
Синтаксис:
DROP EXTERNAL FUNCTION funcname
;
Таблица 4.30. Параметры оператора DROP EXTERNAL FUNCTION
Параметр | Описание |
---|---|
funcname |
Имя внешней функции. |
Оператор DROP EXTERNAL FUNCTION удаляет объявление функции определённой пользователем из базы данных. Если есть зависимости от внешней функции, то удаления не произойдёт и будет выдана соответствующая ошибка.
Удалить объявление внешней функции может любой пользователь, подключенный к базе данных.
См. также: DECLARE EXTERNAL FUNCTION.
BLOB фильтр — объект базы данных, являющийся, по сути, специальным видом внешних функций с единственным назначением: получение объекта BLOB одного формата и преобразования его в объект BLOB другого формата. Форматы объектов BLOB задаются с помощью подтипов BLOB.
Внешние функции для преобразования BLOB типов хранятся в динамических библиотеках и загружаются по необходимости.
Подробнее о подтипах BLOB см. в разделе Бинарные типы данных.
Назначение: Объявление в базе данных BLOB фильтра.
Доступно в: DSQL, ESQL.
Синтаксис:
DECLARE FILTERfiltername
INPUT_TYPE<sub_type>
OUTPUT_TYPE<sub_type>
ENTRY_POINT 'function_name
' MODULE_NAME 'library_name
';<sub_type>
::=number
|<mnemonic>
<mnemonic>
::= binary | text | blr | acl | ranges | summary | format | transaction_description | external_file_description |user_defined
Таблица 4.31. Параметры оператора DECLARE FILTER
Параметр | Описание |
---|---|
filtername |
Имя фильтра. Может содержать до 31 байта. |
sub_type |
Подтип BLOB. См. Подтипы BLOB. |
number |
Номер подтипа BLOB. См. Подтипы BLOB. |
mnemonic |
Мнемоника подтипа BLOB. См. Подтипы BLOB. |
function_name |
Имя экспортируемой функции (точка входа). |
library_name |
Имя модуля, в котором расположен фильтр. |
user_defined |
Определяемая пользователем мнемоника подтипа BLOB. |
Оператор DECLARE FILTER делает доступным BLOB фильтр в базе данных. Имя BLOB фильтра должно быть уникальным среди имён BLOB фильтров.
Подтип может быть задан в виде номера подтипа или мнемоники подтипа. Пользовательские подтипы должны быть представлены отрицательными числами (от -1 до -32768). Не допускается создание двух и более фильтров BLOB с одинаковыми комбинациями входных и выходных типов. Объявление фильтра с уже существующими комбинациями входных и выходных типов BLOB приведёт к ошибке.
Предложение INPUT_TYPE идентифицирует тип преобразуемого объекта (подтип BLOB).
Предложение OUTPUT_TYPE идентифицирует тип создаваемого объекта.
Если вы хотите определить мнемоники для собственных подтипов BLOB, вы можете добавить их в системную таблицу RDB$TYPES, как показано ниже. После подтверждения транзакции мнемоники могут быть использованы для декларации при создании новых фильтров.
INSERT INTO RDB$TYPES (RDB$FIELD_NAME, RDB$TYPE, RDB$TYPE_NAME) VALUES ('RDB$FIELD_SUB_TYPE', -33, 'MIDI');
Значение поля rdb$field_name всегда должно быть 'RDB$FIELD_SUB_TYPE'. Если вы определяете мнемоники в верхнем регистре, то можете использовать их без учёта регистра и без кавычек при объявлении фильтра.
Предложение ENTRY_POINT указывает имя точки входа (имя экспортируемой функции) в модуле.
Предложение MODULE_NAME задаёт имя модуля, в котором находится экспортируемая функция.
По умолчанию модули должны располагаться в папке UDF корневого каталога сервера. Параметр
UDFAccess
в файле firebird.conf
позволяет
изменить ограничения доступа к библиотекам фильтров.
Создать BLOB фильтр может любой пользователь, подключенный к базе данных.
Пример 4.85. Создание BLOB фильтра с использованием номеров подтипов
DECLARE FILTER DESC_FILTER INPUT_TYPE 1 OUTPUT_TYPE -4 ENTRY_POINT 'desc_filter' MODULE_NAME 'FILTERLIB';
Пример 4.86. Создание BLOB фильтра с использованием мнемоник подтипов
DECLARE FILTER FUNNEL INPUT_TYPE blr OUTPUT_TYPE text ENTRY_POINT 'blr2asc' MODULE_NAME 'myfilterlib';
См. также: DROP FILTER.
Назначение: Удаление объявления BLOB фильтра.
Доступно в: DSQL, ESQL.
Синтаксис:
DROP FILTER filtername
;
Оператор DROP FILTER удаляет объявление BLOB фильтра из базы данных. Удаление BLOB фильтра из базы данных делает его не доступным из базы данных, при этом динамическая библиотека, в которой расположена функция преобразования, остаётся не тронутой.
Удалить объявление BLOB фильтра может любой пользователь, подключенный к базе данных.
Последовательность (sequence) или генератор (generator) — объект базы данных, предназначенный для получения уникального числового значения. Термин последовательность является SQL совместимым. Ранее в Interbase и Firebird последовательности называли генераторами.
Независимо от диалекта базы данных последовательности (или генераторы) всегда хранятся как 64-битные целые значения.
Если клиент использует 1 диалект, то сервер передаёт ему значения последовательности, усечённые до 32-битного значения. Если значение последовательности передаются в 32-разрядное поле или переменную, то до тех пор, пока текущее значение последовательности не вышло за границы для 32-битного числа, ошибок не будет. В момент выхода значения последовательности за этот диапазон база данных 3-го диалекта выдаст сообщение об ошибке, а база данных 1-го диалекта будет молча обрезать значения (что также может привести к ошибке — например, если поле, заполняемое генератором, является первичным или уникальным).
В данном разделе описываются вопросы создания, модификации (установка значения последовательности) и удаления последовательностей.
Назначение: Создание новой последовательности (генератора).
Доступно в: DSQL, ESQL.
Синтаксис:
CREATE {SEQUENCE | GENERATOR} seq_name
;
Таблица 4.33. Параметры оператора CREATE SEQUENCE
Параметр | Описание |
---|---|
seq_name |
Имя последовательности (генератора). Может содержать до 31 байта. |
value |
Начальное значение последовательности (генератора). |
Операторы CREATE SEQUENCE и CREATE GENERATOR являются синонимами — оба создают новую последовательность. Вы можете использовать любое из них, но рекомендуется использовать CREATE SEQUENCE, если вам важно соответствие стандарту.
В момент создания последовательности ей устанавливается значение равное 0. В дальнейшем при обращении к конструкции NEXT VALUE FOR её значение увеличивается на единицу. Значение последовательности изменяется также при обращении к функции GEN_ID, где в качестве параметра указывается имя последовательности и значение приращения.
Создать последовательность (генератор) может любой пользователь, присоединившийся к базе данных.
Пример 4.88. Создание последовательности
Создание последовательности EMP_NO_GEN.
CREATE SEQUENCE EMP_NO_GEN;
См. также: ALTER SEQUENCE, SET GENERATOR, DROP SEQUENCE, NEXT VALUE FOR, GEN_ID.
Назначение: Изменение последовательности (генератора).
Доступно в: DSQL, ESQL.
Синтаксис:
ALTER SEQUENCEseq_name
RESTART WITHnew_val
;
Таблица 4.34. Параметры оператора ALTER SEQUENCE
Параметр | Описание |
---|---|
seq_name |
Имя последовательности (генератора). |
new_val |
Новое значение последовательности (генератора). 64 битное целое в диапазоне от -263 .. 263 + 1 |
Оператор ALTER SEQUENCE устанавливает значение последовательности или генератора в заданное значение.
Неосторожное использование оператора ALTER SEQUENCE (изменение значения последовательности или генератора) может привести к нарушению логической целостности данных.
Установить значение последовательности (генератора) может любой пользователь, присоединившийся к базе данных.
Пример 4.89. Изменение последовательности
Установка для последовательности EMP_NO_GEN значения 145.
ALTER SEQUENCE EMP_NO_GEN RESTART WITH 145;
См. также: SET GENERATOR, CREATE SEQUENCE, DROP SEQUENCE, NEXT VALUE FOR, GEN_ID.
Назначение: Удаление последовательности (генератора).
Доступно в: DSQL, ESQL.
Синтаксис:
DROP {SEQUENCE | GENERATOR} seq_name
;
Таблица 4.35. Параметры оператора DROP SEQUENCE
Параметр | Описание |
---|---|
seq_name |
Имя последовательности (генератора). |
Операторы DROP SEQUENCE и DROP GENERATOR эквивалентны: оба удаляют существующую последовательность (генератор). Вы можете использовать любое из них, но рекомендуется использовать DROP SEQUENCE.
При наличии зависимостей для существующей последовательности (генератора) удаления не будет выполнено.
Удалить последовательность может любой пользователь, подключенный к базе данных.
См. также: CREATE SEQUENCE, ALTER SEQUENCE.
Назначение: Устанавливает значение последовательности или генератора в заданное значение.
Доступно в: DSQL, ESQL.
Синтаксис:
SET GENERATORseq_name
TOnew_val
;
Таблица 4.36. Параметры оператора SET GENERATOR
Параметр | Описание |
---|---|
seq_name |
Имя последовательности (генератора). |
new_val |
Новое значение последовательности (генератора). 64 битное целое в диапазоне от -263 .. 263 + 1 |
Оператор SET GENERATOR устанавливает значение последовательности или генератора в заданное значение.
Оператор SET GENERATOR считается устаревшим и оставлен ради обратной совместимости. В настоящее время вместо него рекомендуется использовать стандарт-совместимый оператор ALTER SEQUENCE.
Неосторожное использование оператора SET GENERATOR (изменение значения последовательности или генератора) может привести к потере логической целостности данных.
Установить значение последовательности (генератора) может любой пользователь, присоединившийся к базе данных.
То же самое можно сделать, используя оператор ALTER SEQUENCE
ALTER SEQUENCE EMP_NO_GEN RESTART WITH 145;
См. также: ALTER SEQUENCE, NEXT VALUE FOR, GEN_ID.
Пользовательское исключение (exception) — объект базы данных, описывающий сообщение об ошибке. Исключение можно вызывать и обрабатывать в PSQL коде (см. EXCEPTION, WHEN … DO).
В данном разделе описываются операторы создания, модификации и удаления исключений.
Назначение: Создание пользовательского исключения для использования в PSQL модулях.
Доступно в: DSQL, ESQL.
Синтаксис:
CREATE EXCEPTIONexception_name
'message
';
Таблица 4.37. Параметры оператора CREATE EXCEPTION
Параметр | Описание |
---|---|
exception_name |
Имя исключения. Максимальная длина 31 байта. |
message |
Сообщение об ошибке. Максимальная длина ограничена 1021 символом. |
Оператор CREATE EXCEPTION создаёт новое пользовательское исключение для использования в PSQL модулях. Исключение должно отсутствовать в базе данных, иначе будет выдана соответствующая ошибка.
Имя исключения является стандартным идентификатором. В диалекте 3 оно может быть заключено в двойные кавычки, что делает его чувствительным к регистру. Подробности см. Идентификаторы.
Сообщение исключения сохраняется в наборе символов NONE, т.е. любых символов из однобайтовых наборов символов. Текст сообщения может быть переопределён в PSQL коде во время возбуждения исключения.
Пользовательские исключения хранятся в таблице RDB$EXCEPTION.
Создать исключение может любой пользователь, соединившийся с базой данных.
Пример 4.92. Создание пользовательского исключения
CREATE EXCEPTION E_LARGE_VALUE 'Значение превышает предельно допустимое';
См. также: ALTER EXCEPTION, CREATE OR ALTER EXCEPTION, DROP EXCEPTION, RECREATE EXCEPTION, EXCEPTION.
Назначение: Изменение текста сообщения пользовательского исключения.
Доступно в: DSQL, ESQL.
Синтаксис:
ALTER EXCEPTIONexception_name
'message
';
Таблица 4.38. Параметры оператора ALTER EXCEPTION
Параметр | Описание |
---|---|
exception_name |
Имя исключения. |
message |
Сообщение об ошибке. Максимальная длина ограничена 1021 символом. |
Оператор ALTER EXCEPTION изменяет текст сообщения пользовательского исключения.
Изменять текст сообщения пользовательского исключения может любой пользователь, соединившийся с базой данных.
Пример 4.93. Изменение текста сообщения пользовательского исключения
ALTER EXCEPTION E_LARGE_VALUE 'Значение превышает максимально допустимое';
См. также: CREATE EXCEPTION, CREATE OR ALTER EXCEPTION, RECREATE EXCEPTION.
Назначение: Создание нового или изменение существующего исключения.
Доступно в: DSQL.
Синтаксис:
CREATE OR ALTER EXCEPTIONexception_name
'message
';
Таблица 4.39. Параметры оператора CREATE OR ALTER EXCEPTION
Параметр | Описание |
---|---|
exception_name |
Имя исключения. Максимальная длина 31 байта. |
message |
Сообщение об ошибке. Максимальная длина ограничена 1021 символом. |
Если исключения не существует, то оно будет создано. Уже существующее исключение будет изменено, при этом существующие зависимости исключения будут сохранены.
Пример 4.94. Создание или изменение пользовательского исключения
CREATE OR ALTER EXCEPTION E_LARGE_VALUE
'Значение превышает максимально допустимое';
См. также: CREATE EXCEPTION, ALTER EXCEPTION, RECREATE EXCEPTION.
Назначение: Удаление пользовательского исключения.
Доступно в: DSQL, ESQL.
Синтаксис:
DROP EXCEPTION exception_name
Оператор DROP EXCEPTION удаляет пользовательское исключение. При наличии зависимостей для существующего исключения удаления не будет выполнено.
Удалить пользовательское исключение может любой пользователь, соединившийся с базой данных.
См. также: CREATE EXCEPTION, RECREATE EXCEPTION.
Назначение: Создание или пересоздание пользовательского исключения.
Доступно в: DSQL.
Синтаксис:
RECREATE EXCEPTIONexception_name
'message
';
Таблица 4.41. Параметры оператора RECREATE EXCEPTION
Параметр | Описание |
---|---|
exception_name |
Имя исключения. Максимальная длина 31 байта. |
message |
Сообщение об ошибке. Максимальная длина ограничена 1021 символом. |
Оператор RECREATE EXCEPTION создаёт или пересоздаёт пользовательское исключение. Если исключение с таким именем уже существует, то оператор RECREATE EXCEPTION попытается удалить его и создать новое исключение. При наличии зависимостей для существующего исключения оператор RECREATE EXCEPTION не выполнится.
Пример 4.96. Создание или пересоздание пользовательского исключения
RECREATE EXCEPTION E_LARGE_VALUE
'Значение превышает максимально допустимое';
См. также: CREATE EXCEPTION, ALTER EXCEPTION, CREATE OR ALTER EXCEPTION.
В SQL текстовые строки принадлежат к сортируемым объектам. Это означает, что они подчиняются своим внутренним правилам упорядочения, например, алфавитному порядку. К таким текстовым строкам можно применять операции сравнения (например, "меньше чем" или "больше чем"), при этом значения выражения должны вычисляться согласно определённой последовательности сортировки. Например, выражение 'a'<'b' означает, что 'a' предшествует 'b' в последовательности сортировки. Под выражением 'c'>'b' имеется в виду, что в последовательности сортировки 'с' определено после 'b'. Текстовые строки, включающие больше одного символа, сортируются путём последовательного сравнения символов: сначала сравниваются первые символы двух строк, затем вторые символы и так далее, до тех пор, пока не будет найдено различие между двумя строками. Такое различие управляет порядком сортировки.
Под сравнением (сортировкой) (COLLATION) принято понимать такой объект схемы, который определяет упорядочивающую последовательность (или последовательность сортировки).
Назначение: Добавление новой сортировки (сравнения) для набора символов поддерживаемого в базе данных.
Доступно в: DSQL.
Синтаксис:
CREATE COLLATIONcollname
FORcharset
[FROMbasecoll
| FROM EXTERNAL ('extname
')] [NO PAD | PAD SPACE] [CASE [IN]SENSITIVE] [ACCENT [IN]SENSITIVE] ['<specific-attributes>
'];<specific-attributes>
::=<attribute>
[;<attribute>
...]<attribute>
::=attrname
=attrvalue
Таблица 4.42. Параметры оператора CREATE COLLATION
Параметр | Описание |
---|---|
collname |
Имя сортировки (сравнения). Максимальная длина 31 байта. |
charset |
Набор символов. |
basecoll |
Базовая сортировка (сравнение). |
extname |
Имя сортировки из конфигурационного файла. Чувствительно к регистру. |
Оператор CREATE COLLATION ничего не "создаёт", его целью является сделать сортировку
известной для базы данных. Сортировка уже должна присутствовать в системе, как правило в
файле библиотеки, и должна быть зарегистрирована в файле fbintl.conf
подкаталога intl
корневой директории Firebird.
Необязательное предложение FROM указывает сортировку, на основе которой будет создана
новая сортировка. Такая сортировка должна уже присутствовать в базе данных. Если указано
ключевое слово EXTERNAL, то будет осуществлён поиск сортировки из файла
$fbroot/intl/fbintl.conf
, при этом extname
должно в точности соответствовать имени в конфигурационном файле (чувствительно к
регистру).
Если предложение FROM отсутвует, то Firebird ищет в конфигурационном файле
fbintl.conf
подкаталога intl
корневой директории
сервера сортировку с именем, указанным сразу после CREATE COLLATION. Другими словами,
отсутствие предложения FROM basecoll
эквивалентно заданию FROM
EXTERNAL ('collname
').
При создании сортировки можно указать учитываются ли конечные пробелы при сравнении. Если указана опция NO PAD, то конечные пробелы при сравнении учитываются. Если указана опция PAD SPACE, то конечные пробелы при сравнении не учитываются.
Необязательное предложение CASE позволяет указать будет ли сравнение чувствительно к регистру.
Необязательное предложение ACCENT позволяет указать будет ли сравнение чувствительно к акцентированным буквам (например, «е» и «ё»).
В операторе CREATE COLLATION можно также указать специфичные атрибуты для сортировки. Ниже в таблице приведён список доступных специфичных атрибутов. Не все атрибуты применимы ко всем сортировкам. Если атрибут не применим к сортировке, но указан при её создании, то это не вызовет ошибки.
Имена специфичных атрибутов чувствительны к регистру.
«1 bpc» в таблице указывает на то, что атрибут действителен для сортировок наборов символов, использующих 1 байт на символ (так называемый узкий набор символов), а «UNI» — для юникодных сортировок.
Таблица 4.43. Список доступных специфичных атрибутов COLLATION
Имя | Значение | Валидность | Описание |
---|---|---|---|
DISABLE-COMPRESSIONS | 0, 1 | 1 bpc | Отключает сжатия (иначе сокращения). Сжатия заставляют определённые символьные последовательности быть сортированными как атомарные модули, например, испанские c + h как единственный символ ch. |
DISABLE-EXPANSIONS | 0, 1 | 1 bpc | Отключение расширений. Расширения позволяют рассматривать определённые символы (например, лигатуры или гласные умляуты) как последовательности символов и соответственно сортировать. |
ICU-VERSION | default или
M.m |
UNI | Задаёт версию библиотеки ICU для использования. Допустимые значения
определены в соответствующих элементах <intl_module> в файле
intl/fbintl.conf . Формат: либо строка «default» или
основной и дополнительный номер версии, как «3.0» (оба без кавычек).
|
LOCALE | xx_YY |
UNI | Задаёт параметры сортировки языкового стандарта. Требуется полная версия библиотеки ICU. Формат строки: «du_NL» (без кавычек). |
MULTI-LEVEL | 0, 1 | 1 bpc | Использование нескольких уровней сортировки. |
NUMERIC-SORT | 0, 1 | UNI | Обрабатывает непрерывные группы десятичных цифр в строке как атомарные модули и сортирует их в числовой последовательности (известна как естественная сортировка). |
SPECIALS-FIRST | 0, 1 | 1 bpc | Сортирует специальные символы (пробелы и т.д.) до буквенно-цифровых символов. |
Если вы хотите добавить в базу данных новый набор символов с его умалчиваемой
сортировкой, то зарегистрируйте и выполните хранимую процедуру
sp_register_character_name(name, max_bytes_per_character) из
подкаталога misc/intl.sql
установки Firebird. Для нормальной работы
с набором символов, он должен присутствовать в вашей операционной системе, и
зарегистрирован в файле fbintl.conf
поддиректории
intl
.
Создать новую сортировку может любой пользователь, подключенный к базе данных.
Пример 4.97. Создание сортировки с использованием имени, найденном в файле fbintl.conf (регистро-чувствительно).
CREATE COLLATION ISO8859_1_UNICODE FOR ISO8859_1;
Пример 4.98. Создание сортировки с использованием специального (заданного пользователем) названия («external» имя должно в точности соответствовать имени в файле fbintl.conf).
CREATE COLLATION LAT_UNI FOR ISO8859_1 FROM EXTERNAL ('ISO8859_1_UNICODE');
Пример 4.99. Создание регистронезависимой сортировки на основе уже присутствующей в базе данных.
CREATE COLLATION ES_ES_NOPAD_CI
FOR ISO8859_1
FROM ES_ES
NO PAD
CASE INSENSITIVE;
Пример 4.100. Создание регистронезависимой сортировки на основе уже присутствующей в базе данных со специфичными атрибутами.
CREATE COLLATION ES_ES_CI_COMPR FOR ISO8859_1 FROM ES_ES CASE INSENSITIVE 'DISABLE-COMPRESSIONS=0';
Пример 4.101. Создание регистронезависимой сортировки по значению чисел (так называемой натуральной сортировки).
CREATE COLLATION nums_coll FOR UTF8 FROM UNICODE CASE INSENSITIVE 'NUMERIC-SORT=1'; CREATE DOMAIN dm_nums AS varchar(20) CHARACTER SET UTF8 COLLATE nums_coll; -- original (manufacturer) numbers CREATE TABLE wares(id int primary key, articul dm_nums ...);
См. также: DROP COLLATION.
Назначение: Удаление существующей сортировки.
Доступно в: DSQL.
Синтаксис:
DROP COLLATION collname
;
Оператор DROP COLLATION удаляет указанную сортировку. Сортировка должна присутствовать в базе данных, иначе будет выдана соответствующая ошибка.
Если вы хотите удалить в базе данных набор символов со всеми его сортировками, то
зарегистрируйте и выполните хранимую процедуру sp_unregister_character_set(name) из подкаталога
misc/intl.sql
установки Firebird.
Удалить сортировку может любой пользователь, подключенный к базе данных.
См. также: CREATE COLLATION.
Назначение: Установка сортировки по умолчанию для набора символов.
Доступно в: DSQL.
Синтаксис:
ALTER CHARACTER SETcharset
SET DEFAULT COLLATIONcollation
;
Таблица 4.45. Параметры оператора ALTER CHARACTER SET
Параметр | Описание |
---|---|
charset |
Набор символов. |
collation |
Сортировка. |
Оператор ALTER CHARACTER SET изменяет сортировку по умолчанию для указанного набора символов. Это повлияет на использование набора символов в будущем, кроме случаев, когда явно переопределена сортировка COLLATE. Сортировка существующих доменов, столбцов и переменных PSQL при этом не будет изменена.
Если сортировка по умолчанию была изменена для набора символов базы данных (тот, что был указан при создании базы данных), то также изменяется и сортировка по умолчанию для базы данных.
Если сортировка по умолчанию была изменена для набора символов, который был указан при подключении, строковые константы будут интерпретироваться в соответствии с новыми параметрами сортировки (если набор символов и/или сортировка не переопределяются).
Объекты базы данных и сама база данных могут содержать примечания. Это удобное средство документирования во время разработки базы данных и её поддержки.
Назначение: Документирование метаданных.
Доступно в: DSQL, ESQL.
Синтаксис:
COMMENT ON<object>
IS {'sometext
' | NULL}<object>
::= DATABASE |<basic-type>
objectname
| COLUMNrelationname
.fieldname
| PARAMETERprocname
.paramname
<basic-type>
::= CHARACTER SET | COLLATION | DOMAIN | EXCEPTION | EXTERNAL FUNCTION | FILTER | GENERATOR | INDEX | PROCEDURE | ROLE | SEQUENCE | TABLE | TRIGGER | VIEW
Таблица 4.46. Параметры оператора COMMENT ON
Параметр | Описание |
---|---|
sometext |
Текст комментария. |
basic-type |
Тип объекта метаданных. |
objectname |
Имя объекта метаданных. |
relationname |
Имя таблицы или представления. |
filedname |
Имя поля таблицы или представления. |
procname |
Имя хранимой процедуры. |
paramname |
Имя параметра хранимой процедуры. |
Оператор COMMENT ON добавляет комментарии для объектов базы данных (метаданных). Комментарии при этом сохраняются в текстовые поля RDB$DESCRIPTION типа BLOB соответствующей системной таблицы (из этих полей клиентское приложение может просмотреть комментарии).
Если вы вводите пустой комментарий (''), то он будет сохранен в базе данных как NULL.
Только владелец объекта для которого устанавливается комментарий и администраторы имеют привилегии на использование COMMENT ON.
Пример 4.104. Добавление комментария для текущей базы данных.
COMMENT ON DATABASE IS 'Это тестовая (''my.fdb'') БД';
Пример 4.106. Добавление комментария для поля таблицы.
COMMENT ON COLUMN METALS.ISALLOY
IS '0 = чистый металл, 1 = сплав';
Пример 4.107. Добавление комментария для параметра процедуры.
COMMENT ON PARAMETER ADD_EMP_PROJ.EMP_NO
IS 'Код сотрудника';
Назначение: Выборка данных.
Доступно в: DSQL, ESQL, PSQL.
Синтаксис:
[WITH [RECURSIVE]<cte>
[,<cte>
...]] SELECT [FIRSTm
] [SKIPn
] [DISTINCT | ALL]<columns>
FROMsource
[[AS]alias
] [<joins>
] [WHERE<condition>
] [GROUP BY<grouping-list>
[HAVING<aggregate-condition>
]] [PLAN<plan-expr>
] [UNION [DISTINCT | ALL]<other-select>
] [ORDER BY<ordering-list>
] [ROWSm
[TOn
]] [FOR UPDATE [OF<columns>
]] [WITH LOCK] [INTO<variables>
]<variables>
::= [:]varname
[, [:]varname
...]
Описание:
Оператор (команда) SELECT извлекает данные из базы данных и передаёт их в приложение или в вызывающую SQL команду. Данные возвращаются в виде набора строк (которых может быть 0 или больше), каждая строка содержит один или более столбцов или полей. Совокупность возвращаемых строк является результирующим набором данных команды.
Следующие части команды SELECT являются обязательными:
Ключевое слово SELECT, за которым следует список полей. Эта часть определяет, что запрашивается из базы данных;
Ключевое слово FROM, за которым следует объект выборки (например, таблица). Эта часть сообщает серверу, где следует искать запрашиваемые данные.
В простейшей форме SELECT извлекает ряд полей из единственной таблицы, например:
SELECT id, name, address FROM contacts
Или, для того чтобы извлечь все поля таблицы:
SELECT * FROM contacts
На практике команда SELECT обычно выполняется с выражением WHERE, которое ограничивает возвращаемый набор данных. Также, полученный набор данных обычно сортируется с помощью выражения ORDER BY, дополнительно ограничивается (с целью организации постраничного просмотра данных) выражениями FIRST ... SKIP или ROWS.
Список полей может содержать различные типы выражений вместо имён полей, а источник необязательно должен быть таблицей или представлением, он так же может быть производной таблицей (derived table), общим табличным выражением (CTE) или селективной хранимой процедурой.
Несколько источников данных могут быть соединены с помощью выражения JOIN, и несколько результирующих наборов данных могут быть скомбинированы с использованием выражения UNION.
В следующих секциях мы подробно рассмотрим все выражения для команды SELECT и их использование.
Назначение: Получение части строк из упорядоченного набора.
Синтаксис:
SELECT [FIRST<m>
] [SKIP<n>
] FROM ... ...<m>
,<n>
::=integer literal
|query parameter
| (integer-expression
)
Таблица 5.1. Параметры предложений FIRST и SKIP
Параметр | Описание |
---|---|
integer literal |
Целочисленный литерал. |
query parameter |
Параметр запроса. ? — в DSQL и
:paramname — в PSQL.
|
integer-expression |
Выражение, возвращающее целочисленное значение. |
FIRST и SKIP используются только в Firebird, они не включены в стандарт SQL. Рекомендуется использовать ROWS везде, где это возможно.
Выражение FIRST <m>
ограничивает результирующий
набор данным указанным числом записей.
Выражение SKIP <n>
пропускает указанное число
записей перед выдачей результирующего набора данных.
Когда эти выражения используются совместно, например, FIRST
m
SKIP n
, то в результате
n
записей будет пропущено и, из оставшихся,
m
записей будет возвращено в результирующем наборе
данных.
FIRST и SKIP являются необязательными выражениями.
Разрешается использовать SKIP 0 – в этом случае 0 записей будет пропущено;
В случае использования FIRST 0 будет возвращён пустой набор записей;
Отрицательные значения FIRST и SKIP вызовут ошибку;
Если указанное в SKIP значение превышает размер результирующего набора данных, то вернётся пустой набор данных;
Если число записей в наборе данных (или остаток после применения SKIP) меньше, чем заданное в FIRST значение, то соответственно меньшее количество записей будет возвращено;
Любой аргумент FIRST или SKIP, который не является целым числом или параметром SQL, должен был заключён в круглые скобки. Это, означает, что в случае использования вложенной команды SELECT в качестве параметра для FIRST или SKIP, он должен быть вложен в две пары скобок.
Существует ошибка при использовании FIRST в подзапросах. Этот запрос
DELETE FROM MYTABLE
WHERE ID IN (SELECT FIRST 10 ID FROM MYTABLE)
удалит ВСЕ записи из таблицы.
Подзапрос каждый раз при удалении выбирает 10 строк, удаляет их — и так повторяется до тех пор, пока таблица не станет пустой. Знайте об этом! Или лучше: использовать указание ROWS в операторе DELETE.
Следующий запрос вернёт первые 10 имён из таблицы PEOPLE (имена также будут отсортированы, см. ниже раздел ORDER BY):
SELECT FIRST 10 id, name
FROM People
ORDER BY name ASC
Следующий запрос вернёт все записи из таблицы PEOPLE, за исключением первых 10 имён:
SELECT SKIP 10 id, name
FROM People
ORDER BY name ASC
А этот запрос вернёт последние 10 записей (обратите внимание на двойные скобки):
SELECT SKIP ((SELECT COUNT(*) - 10 FROM People))
id, name
FROM People
ORDER BY name ASC
Этот запрос вернёт строки 81-100 из таблицы PEOPLE:
SELECT FIRST 20 SKIP 80 id, name FROM People ORDER BY name ASC
См. также: ROWS.
Список полей содержит одно или более выражений, разделённых запятыми. Результатом
каждого выражения является значение соответствующего поля в наборе данных команды
SELECT. Исключением является выражение *
(«звёздочка»), которое возвращает все поля отношения.
Синтаксис:
SELECT [...] [DISTINCT | ALL]<output-column>
[,<output-column>
...] [...] FROM ...<output-column>
::= [qualifier
.]* |<value-expression>
[COLLATEcollation
] [[AS]alias
]<value-expression>
::= [qualifier
.]table-column
| [qualifier
.]view-column
| [qualifier
.]selectable-SP-outparm
|constant
| NULL |context-variable
|function-call
|single-value-subselect
|CASE-construct
|other-single-value-expr
Таблица 5.2. Параметры списка полей оператора SELECT
Параметр | Описание |
---|---|
qualifier |
Имя таблицы (представления) или псевдоним таблицы (представления, хранимой процедуры, производной таблицы). |
collation |
Существующее имя сортировки (только для столбцов символьных типов). |
alias |
Псевдоним поля. |
table-column |
Столбец таблицы. |
view-column |
Столбец представления. |
selectable-SP-outparm |
Выходной параметр селективной хранимой процедуры. |
constant |
Константа. |
context-variable |
Контекстная переменная. |
function-call |
Вызов скалярной или агрегатной функции. |
single-value-subselect |
Подзапрос, возвращающий единственное скалярное значение (сингелтон). |
CASE-construct |
Конструкция CASE. |
other-single-value-expr |
Любое другое выражение, возвращающее единственное значение типа данных Firebird или NULL. |
Хорошим тоном является указание полного имени поля вместе с именем алиаса или таблицы/представления/хранимой процедуры, к которой это поле принадлежит.
Указание полного имени становится обязательным в случае, если поле с одним и тем же именем находится в более чем одной таблице, участвующей в объединении.
Алиасы (псевдонимы) заменяют оригинальное имя таблицы/ представления/ хранимой процедуры: как только определён алиас для соответствующего отношения, использовать оригинальное имя нельзя.
В начало списка полей могут быть добавлены ключевые слова DISTINCT или ALL:
DISTINCT удаляет дубликаты строк: то есть, если две или более записей содержат одинаковые значения во всех соответствующих полях, только одна из этих строк будет включена в результирующий набор данных.
ALL включает все строки в результирующий набор данных. ALL включено по умолчанию и поэтому редко используется: явное указание поддерживается для совместимости со стандартом SQL.
Выражение COLLATE не изменяет содержимое поля, однако, если указать COLLATE для определённого поля, то это может изменить чувствительность к регистру символов или к акцентам (accent sensitivity), что, в свою очередь, может повлиять на:
Порядок сортировки, в случае если это поле указано в выражении ORDER BY;
Группировку, в случае если это поле указано в выражении GROUP BY;
Количество возвращаемых строк, если используется DISTINCT.
Простой SELECT использующий только имена полей:
SELECT cust_id, cust_name, phone
FROM customers
WHERE city = 'London'
Запрос с конкатенацией и вызовом функции в списке полей:
SELECT
'Mr./Mrs. ' || lastname,
street,
zip,
upper(city)
FROM contacts
WHERE date_last_purchase(id) = current_date
Запрос с двумя подзапросами:
SELECT p.fullname, (SELECT name FROM classes c WHERE c.id = p.class) AS class, (SELECT name FROM mentors m WHERE m.id = p.mentor) AS mentor FROM pupils p
Следующий запрос делает то же самое, что и предыдущий, только с использованием соединения таблиц (JOIN) вместо подзапросов:
SELECT p.fullname, c.name AS class, m.name AS mentor FROM pupils p JOIN classes c ON c.id = p.class JOIN mentors m ON m.id = p.mentor
Этот запрос использует конструкцию CASE для определения корректного обращения, например, при рассылке сообщений конкретному человеку:
SELECT CASE upper(sex) WHEN 'F' THEN 'Mrs.' WHEN 'M' THEN 'Mr.' ELSE '' END AS title, lastname, address FROM employees
Запрос к хранимой процедуре:
SELECT * FROM interesting_transactions(2010, 3, 'S') ORDER BY amount
Выборка полей производной таблицы. Производная таблица – это заключённый в скобки оператор SELECT, результат которого используется в запросе уровнем выше, как будто является обычной таблицей или представлением.
SELECT fieldcount, COUNT(relation) AS num_tables FROM (SELECT r.rdb$relation_name AS relation, COUNT(*) AS fieldcount FROM rdb$relations r JOIN rdb$relation_fields rf ON rf.rdb$relation_name = r.rdb$relation_name GROUP BY relation) GROUP BY fieldcount
Запрос к контекстной переменной (CURRENT_TIME):
SELECT current_time FROM rdb$database
Для тех, кто не знаком с RDB$DATABASE: это системная таблица, которая всегда существует во всех базах данных Firebird и всегда содержит только одну строку. И, хотя эта таблица не была создана специально для этой цели, стало распространённой практикой среди разработчиков Firebird выполнять запросы к этой таблице в случае, если нужно выполнить запрос, не привязанный ни к какой таблице, в котором результат получается из выражений, указанных в списке полей оператора SELECT. Например:
SELECT power(12, 2) AS twelve_squared, power(12, 3) AS twelve_cubed FROM rdb$database
И, наконец, пример запроса к самой таблице RDB$DATABASE, с помощью которого можно получить кодировку по умолчанию данной БД:
SELECT rdb$character_set_name FROM rdb$database
См. также: Скалярные функции, Агрегатные функции, Контекстные переменные, CASE, Подзапросы.
Выражение FROM определяет источники, из которых будут отобраны данные. В простейшей форме, это может быть единственная таблица или представление. Однако источниками также могут быть хранимая процедура, производная таблица или общее табличное выражение (CTE). Различные виды источников могут комбинироваться с использованием разнообразных видов соединений (JOIN).
Этот раздел посвящён запрос из единственного источника. Соединения рассматриваются в следующем разделе.
Синтаксис:
SELECT ... FROM<source>
[<joins>
] [...]<source>
::= {table
|view
|selectable-stored-procedure
[(args
)] |<derived-table>
|<common-table-expression>
} [[AS]alias
]<derived-table>
::= (select-statement
) [[AS]alias
] [(<column-aliases>
)]<common-table-expression>
::= WITH [RECURSIVE]<cte-def>
[,<cte-def>
...]select-statement
<cte-def>
::=name
[(<column-aliases>
)] AS (select-statement
)<column-aliases>
::=column-alias
[,column-alias
...]
Таблица 5.3. Параметры предложения FROM
Параметр | Описание |
---|---|
table |
Таблица. |
view |
Представление. |
selectable-stored-procedure |
Селективная хранимая процедура. |
args |
Аргументы селективной хранимой процедуры. |
derived-table |
Производная таблица. |
cte-def |
Общее табличное выражение (CTE). |
select-statement |
Произвольный SELECT запрос. |
column-alias |
Алиас столбца CTE или производной таблицы. |
name |
Имя CTE. |
alias |
Псевдоним (алиас) для одного из источников данных (таблицы, представления, процедуры, CTE, производной таблицы). |
При выборке из таблицы или представления предложение FROM не требует ничего кроме его имени. Псевдоним (алиас) может быть полезен или даже необходим при использовании подзапросов, которые соотнесены с главным запросом (обычно подзапросы являются коррелированными).
SELECT id, name, sex, age FROM actors WHERE state = 'Ohio' SELECT * FROM birds WHERE type = 'flightless' ORDER BY family, genus, species SELECT firstname, middlename, lastname, date_of_birth, (SELECT name FROM schools s WHERE p.school = s.id) schoolname FROM pupils p WHERE year_started = 2012 ORDER BY schoolname, date_of_birth
Если вы дадите таблице или представлению псевдоним (алиас), то вы должны везде использовать этот псевдоним, а не имя таблицы, при обращении к именам столбцов.
Корректное использование:
SELECT PEARS FROM FRUIT SELECT FRUIT.PEARS FROM FRUIT SELECT PEARS FROM FRUIT F SELECT F.PEARS FROM FRUIT F
Некорректное использование:
SELECT FRUIT.PEARS FROM FRUIT F
Селективная хранимая процедура (т.е. с возможностью выборки) должна удовлетворять следующим условиям:
Содержать, по крайней мере, один выходной параметр;
Использовать ключевое слово SUSPEND таким образом, чтобы вызывающий запрос могу выбирать выходные строки одну за другой, также как выбираются строки таблицы или представления.
Выходные параметры селективной хранимой процедуры с точки зрения команды SELECT соответствуют полям обычной таблицы.
Выборка из хранимой процедуры без входных параметров осуществляется точно так же, как обычная выборка из таблицы:
SELECT *
FROM suspicious_transactions
WHERE assignee = 'Dmitrii'
Если хранимая процедура требует входные параметры, то они должны быть указаны в скобках после имени процедуры:
SELECT name, az, alt FROM visible_stars('Brugge', current_date, '22:30') WHERE alt >= 20 ORDER BY az, alt
Значения для опциональных параметров (то есть, параметров, для которых определены значения по умолчанию) могут быть указаны или опущены.
Однако если параметры задаются частично, то пропущенные параметры должны быть в конце перечисления внутри скобок.
Если предположить, что процедура visible_stars из предыдущего примера имеет два опциональных параметра spectral_class (varchar(12)) и min_magn (numeric(3,1)), то следующие команды будут корректными:
SELECT name, az, alt FROM visible_stars('Brugge', current_date, '22:30') SELECT name, az, alt FROM visible_stars('Brugge', current_date, '22:30', 4.0)
А вот этот запрос не будет корректным:
SELECT name, az, alt FROM visible_stars('Brugge', current_date, 4.0)
Алиас для селективной хранимой процедуры указывается после списка параметров:
SELECT number, (SELECT name FROM contestants c WHERE c.number = gw.number) FROM get_winners('#34517', 'AMS') gw
Если вы указываете поле (выходной параметр) с полным именем процедуры, не включайте в это имя список параметров процедуры:
SELECT number, (SELECT name FROM contestants c WHERE c.number = get_winners.number) FROM get_winners('#34517', 'AMS')
См. также: Хранимые процедуры, CREATE PROCEDURE.
Производная таблица — это корректная команда SELECT, заключённая в круглые скобки, опционально обозначенная псевдонимом таблицы и псевдонимами полей.
Синтаксис:
(select-query
) [[AS]derived-table-alias
] [(<derived-column-aliases>
)]<derived-column-aliases>
:=column-alias
[,column-alias
...]
Возвращаемый набор данных такого оператора представляет собой виртуальную таблицу, к которой можно составлять запросы, так как будто это обычная таблица.
Производная таблица в запросе ниже выводит список имён таблиц в базе данных и количество столбцов в них. Запрос к производной таблице выводит количество полей, и количество таблиц с таким количеством полей.
SELECT FIELDCOUNT, COUNT(RELATION) AS NUM_TABLES FROM (SELECT R.RDB$RELATION_NAME RELATION, COUNT(*) AS FIELDCOUNT FROM RDB$RELATIONS R JOIN RDB$RELATION_FIELDS RF ON RF.RDB$RELATION_NAME = R.RDB$RELATION_NAME GROUP BY RELATION) GROUP BY FIELDCOUNT
Тривиальный пример, демонстрирующий использование псевдонима производной таблицы и списка псевдонимов столбцов (оба опциональные):
SELECT DBINFO.DESCR, DBINFO.DEF_CHARSET FROM (SELECT * FROM RDB$DATABASE) DBINFO (DESCR, REL_ID, SEC_CLASS, DEF_CHARSET)
Производные таблицы могут быть вложенными;
Производные таблицы могут быть объединениями и использоваться в объединениях. Они могут содержать агрегатные функции, подзапросы и соединения, и сами по себе могут быть использованы в агрегатных функциях, подзапросах и соединениях. Они также могут быть хранимыми процедурами или запросами из них. Они могут иметь предложения WHERE, ORDER BY и GROUP BY, указания FIRST, SKIP или ROWS и т.д.;
Каждый столбец в производной таблице должен иметь имя. Если этого нет по своей природе (например, потому что это — константа), то надо в обычном порядке присвоить псевдоним или добавить список псевдонимов столбцов в спецификации производной таблицы;
Список псевдонимов столбцов опциональный, но если он присутствует, то должен быть полным (т.е. он должен содержать псевдоним для каждого столбца производной таблицы);
Оптимизатор может обрабатывать производные таблицы очень эффективно. Однако если производная таблица включена во внутреннее соединение и содержит подзапрос, то никакой порядок соединения не может быть использован оптимизатором.
Приведём пример того, как использование производных таблиц может упростить решение некоторой задачи.
Предположим, что у нас есть таблица COEFFS, которая содержит коэффициенты для ряда квадратных уравнений, которые мы собираемся решить. Она может быть определена примерно так:
CREATE TABLE coeffs (
a DOUBLE PRECISION NOT NULL,
b DOUBLE PRECISION NOT NULL,
c DOUBLE PRECISION NOT NULL,
CONSTRAINT chk_a_not_zero CHECK (a <> 0)
)
В зависимости от значений коэффициентов a, b и c, каждое уравнение может иметь ноль, одно или два решения. Мы можем найти эти решения с помощью одноуровневого запроса к таблице COEFFS, однако код такого запроса будет громоздким, а некоторые значения (такие, как дискриминанты) будут вычисляться несколько раз в каждой строке.
Если использовать производную таблицу, то запрос можно сделать гораздо более элегантным:
SELECT IIF (D >= 0, (-b - sqrt(D)) / denom, NULL) AS sol_1, IIF (D > 0, (-b + sqrt(D)) / denom, NULL) AS sol_2 FROM (SELECT b, b*b - 4*a*c, 2*a FROM coeffs) (b, D, denom)
Если мы захотим показывать коэффициенты рядом с решениями уравнений, то мы можем модифицировать запрос следующим образом:
SELECT a, b, c, IIF (D >= 0, (-b - sqrt(D)) / denom, NULL) sol_1, IIF (D > 0, (-b + sqrt(D)) / denom, NULL) sol_2 FROM (SELECT a, b, c, b*b - 4*a*c AS D, 2*a AS denom FROM coeffs)
Обратите внимание, что в первом запросе мы назначили алиасы для всех полей производной таблицы в виде списка после таблицы, а во втором, по мере необходимости, добавляем алиасы внутри запроса производной таблицы. Оба этих метода корректны, так как при правильном применении гарантируют, что каждое поле производной таблицы имеет уникальное имя.
На самом деле все столбцы, вычисляемые в производной таблице, будут перевычислены столько раз, сколько раз они указываются в основном запросе. Это важно может привести к неожиданным результатам при использовании недетерминированных функций. Следующий пример показывает сказанное:
SET LIST ON; SELECT UUID_TO_CHAR(X) AS C1, UUID_TO_CHAR(X) AS C2, UUID_TO_CHAR(X) AS C3 FROM (SELECT GEN_UUID() AS X FROM RDB$DATABASE) T;
результатом этого запроса будет
C1 80AAECED-65CD-4C2F-90AB-5D548C3C7279 C2 C1214CD3-423C-406D-B5BD-95BF432ED3E3 C3 EB176C10-F754-4689-8B84-64B666381154
Для материализации результата функции GEN_UUID вы можете воспользоваться следующим способом:
SET LIST ON; SELECT UUID_TO_CHAR(X) AS C1, UUID_TO_CHAR(X) AS C2, UUID_TO_CHAR(X) AS C3 FROM (SELECT GEN_UUID() AS X FROM RDB$DATABASE UNION ALL SELECT NULL FROM RDB$DATABASE WHERE 1=0) T;
результатом этого запроса будет
C1 80AAECED-65CD-4C2F-90AB-5D548C3C7279 C2 80AAECED-65CD-4C2F-90AB-5D548C3C7279 C3 80AAECED-65CD-4C2F-90AB-5D548C3C7279
или завернуть функцию GEN_UUID в подзапрос
SELECT UUID_TO_CHAR(X) AS C1, UUID_TO_CHAR(X) AS C2, UUID_TO_CHAR(X) AS C3 FROM (SELECT (SELECT GEN_UUID() FROM RDB$DATABASE) AS X FROM RDB$DATABASE) T;
Эта особенность текущей реализации и она может быть изменена в следующих версиях сервера.
Общие табличные выражения являются более сложной и более мощной вариацией производных таблиц. CTE состоят из преамбулы, начинающейся с ключевого слова WITH, которая определяет одно или более общих табличных выражений (каждое из которых может иметь список алиасов полей). Основной запрос, который следует за преамбулой, может обращаться к CTE так, как будто обычные таблицы. CTE доступны любой части запроса ниже точки своего объявления.
Подробно CTE описываются в разделе Общие табличные выражения CTE (WITH ... AS ... SELECT), а здесь приведены лишь некоторые примеры использования.
Следующий запрос представляет наш пример с производной таблицей в варианте для общих табличных выражений:
WITH vars (b, D, denom) AS ( SELECT b, b*b - 4*a*c, 2*a FROM coeffs ) SELECT IIF (D >= 0, (-b - sqrt(D)) / denom, NULL) AS sol_1, IIF (D > 0, (-b + sqrt(D)) / denom, NULL) AS sol_2 FROM vars
Это не слишком большое улучшение по сравнению с вариантом с производными таблицами (за исключением того, что вычисления проводятся до основного запроса). Мы можем ещё улучшить запрос, исключив двойное вычисление sqrt(D) для каждой строки:
WITH vars (b, D, denom) AS ( SELECT b, b*b - 4*a*c, 2*a FROM coeffs ), vars2 (b, D, denom, sqrtD) AS ( SELECT b, D, denom, IIF (D >= 0, sqrt(D), NULL) FROM vars ) SELECT IIF (D >= 0, (-b - sqrtD) / denom, NULL) AS sol_1, IIF (D > 0, (-b + sqrtD) / denom, NULL) AS sol_2 FROM vars2
Текст запроса выглядит более сложным, но он стал более эффективным (предполагая, что исполнение функции SQRT занимает больше времени, чем передача значений переменных b, d и denom через дополнительное CTE).
На самом деле все столбцы, вычисляемые в CTE, будут перевычислены столько раз, сколько раз они указываются в основном запросе. Это важно может привести к неожиданным результатам при использовании недетерминированных функций. Следующий пример показывает сказанное:
SET LIST ON; WITH T(X) AS (SELECT GEN_UUID() FROM RDB$DATABASE) SELECT UUID_TO_CHAR(X) as c1, UUID_TO_CHAR(X) as c2, UUID_TO_CHAR(X) as c3 FROM T
результатом этого запроса будет
C1 80AAECED-65CD-4C2F-90AB-5D548C3C7279 C2 C1214CD3-423C-406D-B5BD-95BF432ED3E3 C3 EB176C10-F754-4689-8B84-64B666381154
Для материализации результата функции GEN_UUID вы можете воспользоваться следующим способом:
WITH T(X) AS (SELECT GEN_UUID() FROM RDB$DATABASE UNION ALL SELECT NULL FROM RDB$DATABASE WHERE 1=0) SELECT UUID_TO_CHAR(X) as c1, UUID_TO_CHAR(X) as c2, UUID_TO_CHAR(X) as c3 FROM T;
результатом этого запроса будет
C1 80AAECED-65CD-4C2F-90AB-5D548C3C7279 C2 80AAECED-65CD-4C2F-90AB-5D548C3C7279 C3 80AAECED-65CD-4C2F-90AB-5D548C3C7279
или завернуть функцию GEN_UUID в подзапрос
WITH T(X) AS (SELECT (SELECT GEN_UUID() FROM RDB$DATABASE) FROM RDB$DATABASE) SELECT UUID_TO_CHAR(X) as c1, UUID_TO_CHAR(X) as c2, UUID_TO_CHAR(X) as c3 FROM T;
Эта особенность текущей реализации и она может быть изменена в следующих версиях сервера.
Конечно, мы могли бы добиться такого результата и с помощью производных таблиц, но это потребовало бы вложить запросы один в другой.
См. также: Общие табличные выражения CTE (WITH ... AS ... SELECT).
Соединения объединяют данные из двух источников в один набор данных. Соединение данных осуществляется для каждой строки и обычно включает в себя проверку условия соединения (join condition) для того, чтобы определить, какие строки должны быть объединены и оказаться в результирующем наборе данных.
Результат соединения также может быть соединён с другим набором данных с помощью следующего соединения.
Существует несколько типов (INNER, OUTER) и классов (квалифицированные, натуральные, и др.) соединений, каждый из которых имеет свой синтаксис и правила.
Синтаксис:
SELECT ... FROM<source>
[<joins>
] [...]<source>
::= {table
|view
|selectable-stored-procedure
[(args
)] |derived-table
|common-table-expression
} [[AS]alias
]<joins>
::=<join>
[<join>
...]<join>
::= [<join-type>
] JOIN<source>
<join-condition>
| NATURAL [<join-type>
] JOIN<source>
| {CROSS JOIN | ,}<source>
<join-type>
::= INNER | {LEFT | RIGHT | FULL} [OUTER]<join-condition>
::= ONcondition
| USING (column-list
)
Таблица 5.4. Параметры предложения JOIN
Параметр | Описание |
---|---|
table |
Таблица. |
view |
Представление. |
selectable-stored-procedure |
Селективная хранимая процедура. |
args |
Аргументы селективной хранимой процедуры. |
derived-table |
Производная таблица. |
common-table-expression |
Общее табличное выражение (CTE). |
alias |
Псевдоним (алиас) для одного из источников данных (таблицы, представления, процедуры, CTE, производной таблицы). |
condition |
Условие соединения. |
column-list |
Список столбцов по которым происходит эквисоединение. |
Соединение всегда соединяет строки из двух наборов данных (которые обычно называются "левый" и "правый"). По умолчанию, только строки, которые удовлетворяет условию соединения (те, которым соответствует хотя бы одна строка из другого набора строк согласно применяемому условию) попадают в результирующий набор данных. Такой тип соединения (который является типом по умолчанию) называется внутренним (INNER JOIN).
Предположим, у нас есть 2 таблицы:
Таблица А:
ID | S |
---|---|
87 | Just some text |
35 | Silence |
Таблица B:
CODE | X |
---|---|
-23 | 56.7735 |
87 | 416.0 |
Если мы соединим эти таблицы с помощью вот такого запроса:
SELECT * FROM A JOIN B ON A.id = B.code
то результат будет:
ID | S | CODE | X |
---|---|---|---|
87 | Just some text | 87 | 416.0 |
То есть, первая строка таблицы А была соединена со второй строкой таблицы B, потому что вместе они удовлетворяют условию соединения "A.id = B.code". Другие строки не имеют соответствия и поэтому не включаются в соединение. Помните, что умолчанию соединение всегда внутреннее (INNER).
Мы можем сделать это явным, указав тип соединения:
SELECT * FROM A INNER JOIN B ON A.id = B.code
но обычно слово inner опускается.
Разумеется, возможны случаи, когда строке в левом наборе данных соответствует несколько строк в правом наборе данных (или наоборот).
В таких случаях все комбинации включаются в результирующих набор данных, и мы можем получить результат вроде этого:
ID | S | CODE | X |
---|---|---|---|
87 | Just some text | 87 | 416.0 |
87 | Just some text | 87 | -1.0 |
-23 | Don't know | -23 | 56.7735 |
-23 | Still don't know | -23 | 56.7735 |
-23 | I give up | -23 | 56.7735 |
Иногда необходимо включить в результат все записи из левого или правого набора данных, вне зависимости от того, есть ли для них соответствующая запись в парном наборе данных. В этом случае необходимо использовать внешние соединения.
Внешнее левое соединение (LEFT OUTER) включает все записи из левого набора данных, и те записи из правого набора, которые удовлетворяют условию соединения.
Внешнее правое соединение (RIGHT OUTER) включает все записи из правого набора данных и те записи из левого набора данных, которые удовлетворяют условию соединения.
Полное внешнее соединение (FULL OUTER) включает все записи из обоих наборов данных.
Во всех внешних соединениях, "дыры" (то есть поля набора данных, в которых нет соответствующей записи) заполняются NULL.
Для обозначения внешнего соединения используются ключевые слова LEFT, RIGHT или FULL с необязательным ключевым словом OUTER.
Рассмотрим различные внешние соединения на примере запросов с указанными выше таблицами A и B:
SELECT * FROM A LEFT OUTER JOIN B ON A.id = B.code
то же самое
SELECT * FROM A LEFT JOIN B ON A.id = B.code
ID | S | CODE | X |
---|---|---|---|
87 | Just some text | 87 | 416.0 |
235 | Silence | <null> | <null> |
SELECT * FROM A RIGHT OUTER JOIN B ON A.id = B.code
то же самое
SELECT * FROM A RIGHT JOIN B ON A.id = B.code
ID | S | CODE | X |
---|---|---|---|
<null> | <null> | -23 | 56.7735 |
87 | Just some text | 87 | 416.0 |
SELECT * FROM A FULL OUTER JOIN B ON A.id = B.code
то же самое
SELECT * FROM A FULL JOIN B ON A.id = B.code
ID | S | CODE | X |
---|---|---|---|
<null> | <null> | -23 | 56.7735 |
87 | Just some text | 87 | 416.0 |
235 | Silence | <null> | <null> |
Явный синтаксис соединения требует указания условия соединения записей. Это условие указывается явно в предложении ON или неявно при помощи предложения USING.
Синтаксис:
<qualified-join>
::= [<join-type>
] JOIN<source>
<join-condition>
<join-type>
::= INNER | {LEFT | RIGHT | FULL} [OUTER]<join-condition>
::= ONcondition
| USING (column-list
)
В синтаксисе явного соединения есть предложение ON, с условием соединения, в котором может быть указано любое логическое выражение, но, как правило, оно содержит условие сравнения между двумя участвующими источниками.
Довольно часто, это условие — проверка на равенство (или ряд проверок на равенство объединённых оператором AND) использующая оператор "=". Такие соединения называются эквисоединениями. (Примеры в главе Внутренние (INNER) и внешние (OUTER) соединения были эквисоединениями).
Примеры соединений с явными условиями:
/* * Выборка всех заказчиков из города Детройт, которые * сделали покупку. */ SELECT * FROM customers c JOIN sales s ON s.cust_id = c.id WHERE c.city = 'Detroit' /* * Тоже самое, но включает в выборку заказчиков, которые * не совершали покупки. */ SELECT * FROM customers c LEFT JOIN sales s ON s.cust_id = c.id WHERE c.city = 'Detroit' /* * Для каждого мужчины выбрать женщин, которые выше него. * Мужчины, для которых такой женщины не существуют, * не будут выключены в выборку. */ SELECT m.fullname AS man, f.fullname AS woman FROM males m JOIN females f ON f.height > m.height /* * Выборка всех учеников, их класса и наставника. * Ученики без наставника буду включены в выборку. * Ученики без класса не будут включены в выборку. */ SELECT p.firstname, p.middlename, p.lastname, c.name, m.name FROM pupils p JOIN classes c ON c.id = p.class LEFT JOIN mentors m ON m.id = p.mentor
Эквисоединения часто сравнивают столбцы, которые имеют одно и то же имя в обеих таблицах. Для таких соединений мы можем использовать второй тип явных соединений, называемый соединением именованными столбцами (Named Columns Joins). Соединение именованными столбцами осуществляются с помощью предложения USING, в котором перечисляются только имена столбцов.
Соединения именованными столбцами доступны только в диалекте 3.
Таким образом, следующий пример:
SELECT * FROM flotsam f JOIN jetsam j ON f.sea = j.sea AND f.ship = j.ship
можно переписать так:
SELECT * FROM flotsam JOIN jetsam USING (sea, ship)
что значительно короче. Результирующий набор несколько отличается, по крайней мере, при использовании "SELECT *":
Результат соединения с явным условием соединения в предложении ON будет содержать каждый из столбцов SEA и SHIP дважды: один раз для таблицы FLOTSAM и один раз для таблицы JETSAM. Очевидно, что они будут иметь они и те же значения;
Результат соединения именованными столбцами, с помощью предложения USING, будет содержать эти столбцы один раз.
Если вы хотите получить в результате соединения именованными столбцами все столбцы, перепишите запрос следующим образом:
SELECT f.*, j.* FROM flotsam f JOIN jetsam j USING (sea, ship)
Для внешних (OUTER) соединений именованными столбцами, существуют дополнительные нюансы, при использовании "SELECT *" или неполного имени столбца. Если столбец строки из одного источника не имеет совпадений со столбцом строки из другого источника, но все равно должен быть включён результат из-за инструкций LEFT, RIGHT или FULL, то объединяемый столбец получит не NULL значение. Это достаточно справедливо, но теперь вы не можете сказать из какого набора левого, правого или обоих пришло это значение. Это особенно обманывает, когда значения пришли из правой части набора данных, потому что "*" всегда отображает для комбинированных столбцов значения из левой части набора данных, даже если используется RIGHT соединение.
Является ли это проблемой, зависит от ситуации. Если это так, используйте "f.*, j.*" подход, продемонстрированный выше, где f и j имена или алиасы двух источников. Или лучше вообще избегать "*" в серьёзных запросах и перечислять все имена столбцов для соединяемых множеств. Такой подход имеет дополнительное преимущество, заставляя вас думать, о том какие данные вы хотите получить и откуда.
Вся ответственность за совместимость типов столбцов между соединяемыми источниками, имена которых перечислены в предложении USING, лежит на вас. Если типы совместимы, но не равны, то Firebird преобразует их в тип с более широким диапазоном значений перед сравнением. Кроме того, это будет типом данных объединённого столбца, который появится в результирующем наборе, если используются "SELECT *" или неполное имя столбца. Полные имена столбцов всегда будут сохранять свой первоначальный тип данных.
Если при соединении именованными столбцами вы используете столбцы соединения в условии отбора WHERE, то всегда используйте уточнённые имена столбцов. В противном случае индекс по этому столбцу не будет задействован.
SELECT 1 FROM t1 a JOIN t2 b USING(x) WHERE x = 0; PLAN JOIN (A NATURAL, B INDEX (RDB$2))
однако
SELECT 1 FROM t1 a JOIN t2 b USING(x) WHERE a.x = 0; -- или 'b.x' PLAN JOIN (A INDEX (RDB$1), B INDEX (RDB$2)) SELECT 1 FROM t1 a JOIN t2 b USING(x) WHERE b.x = 0; PLAN JOIN (A INDEX (RDB$1), B INDEX (RDB$2))
Дело в том, неуточнённый столбец в данном случае неявно заменяется на COALESCE(a.x, b.x). Этот хитрый трюк применяется для устранения неоднозначности имён столбцов, но он же мешает применению индекса.
Взяв за основу соединения именованными столбцами, следующим шагом будет естественное соединение, которое выполняет эквисоединение по всем одноименным столбцам правой и левой таблицы. Типы данных этих столбцов должны быть совместимыми.
Естественные соединения доступны только в диалекте 3.
Синтаксис:
<natural-join>
::= NATURAL [<join-type>
] JOIN<source>
<join-type>
::= INNER | {LEFT | RIGHT | FULL} [OUTER]
Даны две таблицы:
CREATE TABLE TA ( a BIGINT, s VARCHAR(12), ins_date DATE ); CREATE TABLE TB ( a BIGINT, descr VARCHAR(12), x FLOAT, ins_date DATE );
Естественное соединение таблиц TA и TB будет происходить по столбцам a и ins_date и два следующих оператора дадут один и тот же результат:
SELECT * FROM TA NATURAL JOIN TB; SELECT * FROM TA JOIN TB USING (a, ins_date);
Как и все соединения, естественные соединения являются внутренними соединениями по умолчанию, но вы можете превратить их во внешние соединения, указав LEFT, RIGHT или FULL перед ключевым словом JOIN.
Если в двух исходных таблицах не будут найдены одноименные столбцы, то будет выполнен CROSS JOIN.
Перекрёстное соединение или декартово произведение. Каждая строка левой таблицы соединяется с каждой строкой правой таблицы.
Синтаксис:
<cross-join>
::= {CROSS JOIN | , }<source>
Обратите внимание, что синтаксис с использованием запятой является устаревшим. Он поддерживается только для поддержания работоспособности унаследованного программного кода и может быть удалён в будущих версиях.
Перекрёстное соединение двух наборов эквивалентно их соединению по условию тавтологии (условие, которое всегда верно).
Следующие два запроса дадут один и тот же результат:
SELECT * FROM TA CROSS JOIN TB; SELECT * FROM TA JOIN TB ON 1 = 1;
Перекрёстные соединения являются внутренними соединениями, потому что они отбирают строки, для которых есть соответствие — так уж случилось, что каждая строка соответствует! Внешнее перекрёстное соединение, если бы оно существовало, ничего не добавило бы к результату, потому что внешние соединения добавляют записи, по которым нет соответствия, а они не существуют в перекрёстном соединении.
Перекрёстные соединения редко полезны, кроме случаев, когда вы хотите получить список всех возможных комбинаций двух или более переменных. Предположим, вы продаёте продукт, который поставляется в различных размерах, различных цветов и из различных материалов. Если для каждой переменной значения перечислены в собственной таблице, то этот запрос будет возвращать все комбинации:
SELECT m.name, s.size, c.name FROM materials m CROSS JOIN sizes s CROSS JOIN colors c
Firebird отвергает неполные имена полей в запросе, если эти имена полей существуют в более чем одном наборе данных, участвующих в объединении. Это также верно для внутренних эквисоединений, в которых имена полей фигурируют в предложении ON:
SELECT a, b, c FROM TA JOIN TB ON TA.a = TB.a
Существует одно исключение из этого правила: соединения по именованным столбцам и естественные соединения, которые используют неполное имя поля в процессе подбора, могут использоваться законно. Это же относится и к одноименным объединяемым столбцам. Для соединений по именованным столбцам эти столбцы должны быть перечислены в предложении USING. Для естественных соединений это столбцы, имена которых присутствуют в обеих таблицах. Но снова замечу, что, особенно во внешних соединениях, плоское имя colname является не всегда тем же самым что left.colname или right.colname. Типы данных могут отличаться, и один из полных столбцов может иметь значение NULL, в то время как другой нет. В этом случае значение в объединённом, неполном столбце может замаскировать тот факт, что одно из исходных значений отсутствует.
Если соединение происходит с хранимой процедурой, которая не коррелирована с другими потоками данных через входные параметры, то нет никаких особенностей.
В противном случае, есть одна неприятная особенность. Дело в том, что оптимизатор не в состоянии определить зависимость входных параметров процедуры от прочих потоков:
SELECT * FROM MY_TAB JOIN MY_PROC(MY_TAB.F) ON 1 = 1
В данном случае процедура будет поставлена вперед, когда из таблицы MY_TAB ещё не выбрана ни одна запись. Соответственно, на этапе исполнения будет выдана ошибка isc_no_cur_rec (no current record for fetch operation). Обходится данная проблема через явное указание порядка соединения синтаксисом:
SELECT * FROM MY_TAB LEFT JOIN MY_PROC(MY_TAB.F) ON 1 = 1
Эта ошибка оптимизатора исправлена в Firebird 3.0.
Предложение WHERE предназначено для ограничения количества возвращаемых строк, теми которые нас интересуют. Условие после ключевого слова WHERE может быть простым, как проверка "AMOUNT = 3", так и сложным, запутанным выражением, содержащим подзапросы, предикаты, вызовы функций, математические и логические операторы, контекстные переменные и многое другое.
Условие в предложении WHERE часто называют условием поиска, выражением поиска или просто поиск.
В DSQL и ESQL, выражение поиска могут содержать параметры. Это полезно, если
запрос должен быть повторен несколько раз с разными значениями входных параметров. В
строке SQL запроса, передаваемого на сервер, вопросительные знаки используются как
заполнители для параметров. Их называют позиционными параметрами, потому что они не
могут сказать ничего кроме как о позиции в строке. Библиотеки доступа часто
поддерживают именованные параметры в виде :id
,
:amount
, :a
и т.д. Это
более удобно для пользователя, библиотека заботится о трансляции именованных
параметров в позиционные параметры, прежде чем передать запрос на сервер.
Условие поиска может также содержать локальные (PSQL) или хост (ESQL) имена переменных, предваряемых двоеточием.
Синтаксис:
SELECT ...
FROM ...
[...]
WHERE <search-condition>
[...]
Таблица 5.5. Параметры предложения WHERE
Параметр | Описание |
---|---|
search-condition |
Логическое выражение возвращающее TRUE, FALSE и возможно UNKNOWN (NULL). |
Только те строки, для которых условие поиска истинно будут включены в результирующий набор. Будьте осторожны с возможными получаемыми значениями NULL: если вы отрицаете выражение, дающее NULL с помощью NOT, то результат такого выражения все равно будет NULL и строка не пройдёт. Это демонстрируется в одном из ниже приведённых примеров.
SELECT genus, species FROM mammals WHERE family = 'Felidae' ORDER BY genus; SELECT * FROM persons WHERE birthyear IN (1880, 1881) OR birthyear BETWEEN 1891 AND 1898; SELECT name, street, borough, phone FROM schools s WHERE EXISTS (SELECT * FROM pupils p WHERE p.school = s.id) ORDER BY borough, street; SELECT * FROM employees WHERE salary >= 10000 AND position <> 'Manager'; SELECT name FROM wrestlers WHERE region = 'Europe' AND weight > ALL (SELECT weight FROM shot_putters WHERE region = 'Africa'); SELECT id, name FROM players WHERE team_id = (SELECT id FROM teams WHERE name = 'Buffaloes'); SELECT SUM (population) FROM towns WHERE name LIKE '%dam' AND province CONTAINING 'land'; SELECT pass FROM usertable WHERE username = current_user;
Следующий пример показывает, что может быть, если условие поиска вычисляется как NULL.
Предположим у вас есть таблица, в которой находятся несколько детских имён и количество шариков, которыми они обладают.
CHILD | MARBLES |
---|---|
Anita | 23 |
Bob E. | 12 |
Chris | <null> |
Deirdre | 1 |
Eve | 17 |
Fritz | 0 |
Gerry | 21 |
Hadassah | <null> |
Isaac | 6 |
Первое, обратите внимание на разницу между NULL и 0. Известно, что Fritz не имеет шариков вовсе, однако неизвестно количество шариков у Chris и Hadassah.
Теперь, если ввести этот SQL оператор:
SELECT LIST(child) FROM marbletable WHERE marbles > 10
вы получите имена Anita, Bob E., Eve и Gerry. Все эти дети имеют более чем 10 шариков.
Если вы отрицаете выражение:
SELECT LIST(child) FROM marbletable WHERE NOT marbles > 10
запрос вернёт Deirdre, Fritz и Isaac. Chris и Hadassah не будут включены в выборку, так как не известно 10 у них шариков или меньше. Если вы измените последний запрос так:
SELECT LIST(child) FROM marbletable WHERE marbles <= 100
результат будет тем же самым, поскольку выражение NULL <= 10 даёт UNKNOWN. Это не то же самое что TRUE, поэтому Chris и Hadassah не отображены. Если вы хотите что бы в списке были перечислены все "бедные" дети, то измените запрос следующим образом:
SELECT LIST(child)
FROM marbletable
WHERE marbles <= 10 OR marbles IS NULL
Теперь условие поиска становится истинным для Chris и Hadassah, потому что условие "marbles is null" возвращает TRUE в этом случае. Фактически, условие поиска не может быть NULL ни для одного из них.
Наконец, следующие два примера SELECT запросов с параметрами в условии поиска. Как определяются параметры запроса и возможно ли это, зависит от приложения. Обратите внимание, что запросы подобные этим не могут быть выполнены немедленно, они должны быть предварительно подготовлены. После того как параметризированный запрос был подготовлен, пользователь (или вызывающий код) может подставить значения параметров и выполнить его многократно, подставляя перед каждым вызовом новые значения параметров. Как вводятся значения параметров, и проходят ли они предобработку зависит от приложения. В GUI средах пользователь, как правило, вводит значения параметров через одно и более текстовых полей, и щелкает на кнопку "Execute", "Run" или "Refresh".
SELECT name, address, phone FROM stores WHERE city = ? AND class = ? SELECT * FROM pants WHERE model = :model AND size = :size AND color = :col
Последний запрос не может быть передан непосредственно к движку сервера, приложение должно преобразовать его в другой формат, отображая именованные параметры на позиционные параметры.
Предложение GROUP BY соединяет записи, имеющие одинаковую комбинацию значений полей, указанных в его списке, в одну запись. Агрегатные функции в списке выбора применяются к каждой группе индивидуально, а не для всего набора в целом.
Если список выборки содержит только агрегатные столбцы или столбцы, значения которых не зависит от отдельных строк основного множества, то предложение GROUP BY необязательно. Когда предложение GROUP BY опущено, результирующее множество будет состоять из одной строки (при условии, что хотя бы один агрегатный столбец присутствует).
Если в списке выборки содержатся как агрегатные столбцы, так и столбцы, чьи значения зависит от выбираемых строк, то предложение GROUP BY становится обязательным.
Синтаксис:
SELECT ... FROM ... GROUP BY<grouping-item>
[,<grouping-item>
...] [HAVING<grouped-row-condition>
] ...<grouping-item>
::=<non-aggr-select-item>
|<non-aggr-expression>
<non-aggr-select-item>
::=column-copy
|column-alias
|column-position
Таблица 5.6. Параметры предложения GROUP BY
Параметр | Описание |
---|---|
non-aggr-expression |
Любое не агрегатное выражение, которое не включено в список выборки, т.е. невыбираемые столбцы из набора источника или выражения, которые не зависит от набора данных вообще. |
column-copy |
Дословная копия выражения из списка выбора, не содержащего агрегатной функции. |
column-alias |
Псевдоним выражения (столбца) из списка выбора, не содержащего агрегатной функции. |
column-position |
Номер позиции выражения (столбца) из списка выбора, не содержащего агрегатной функции. |
Общее правило гласит, что каждый не агрегированный столбец в SELECT списке, должен быть так же включён в GROUP BY список. Вы можете это сделать тремя способами:
Копировать выражение дословно из списка выбора, например, "class" или "'D:' || upper(doccode)";
Указать псевдоним, если он существует;
Задать положение столбца в виде целого числа, которое находится в диапазоне от 1 до количества столбцов в списке SELECT. Целые значения, полученные из выражений, параметров или просто инварианты будут использоваться в качестве таковых в группировке. Они не будут иметь никакого эффекта, поскольку их значение одинаково для каждой строки.
Если вы группируете по позиции столбца или алиасу, то выражение соответствующее этой позиции (алиасу) будет скопировано из списка выборки SELECT. Это касается и подзапросов, таким образом, подзапрос будет выполняться, по крайней мере, два раза.
В дополнении к требуемым элементам, список группировки так же может содержать:
Столбцы исходной таблицы, которые не включены в список выборки SELECT, или неагрегатные выражения, основанные на таких столбцах. Добавление таких столбцов может дополнительно разбить группы. Но так как эти столбцы не в списке выборки SELECT, вы не можете сказать, какому значению столбца соответствует значение агрегированной строки. Таким образом, если вы заинтересованы в этой информации, вы так же должны включить этот столбец или выражение в список выборки SELECT, что возвращает вас к правилу "каждый не агрегированный столбце в списке выборки SELECT должен быть включён в список группировки GROUP BY";
Выражения, которые не зависят от данных из основного набора, т.е. константы, контекстные переменные, некоррелированные подзапросы, возвращающие единственное значение и т.д. Это упоминается только для полноты картины, т.к. добавление этих элементов является абсолютно бессмысленным, поскольку они не повлияют на группировку вообще. "Безвредные, но бесполезные" элементы так же могут фигурировать в списке выбора SELECT без их копирования в список группировки GROUP BY.
Когда в списке выбора SELECT содержатся только агрегатные столбцы, предложение GROUP BY необязательно:
SELECT COUNT(*), AVG(age)
FROM students
WHERE sex = 'M'
Этот запрос вернёт одну строку с указанием количества студентов мужского пола и их средний возраст. Добавление выражения, которое не зависит от строк таблицы STUDENTS, ничего не меняет:
SELECT COUNT(*), AVG(age), current_date
FROM students
WHERE sex = 'M'
Теперь строка результата будет иметь дополнительный столбец, отображающий текущую дату, но кроме этого, ничего фундаментального не изменилось. Группировка по-прежнему не требуется.
Тем не менее, в обоих приведённых выше примерах это разрешено. Это совершенно справедливо и для запроса:
SELECT COUNT(*), AVG(age)
FROM students
WHERE sex = 'M'
GROUP BY class
и вернёт результат для каждого класса, в котором есть мальчики, перечисляя количество мальчиков и их средний возраст в этой конкретном классе. Если вы также оставите поле CURRENT_DATE, то это значение будет повторяться на каждой строке, что не интересно.
Этот запрос имеет существенный недостаток, хотя он даёт вам информацию о различных классах, но не говорит вам, какая строка к какому классу относится. Для того чтобы получить эту дополнительную часть информации, не агрегатный столбец CLASS должен быть добавлен в список выборки SELECT:
SELECT class, COUNT(*), AVG(age)
FROM students
WHERE sex = 'M'
GROUP BY class
Теперь у нас есть полезный запрос. Обратите внимание, что добавление столбца CLASS делает предложение GROUP BY обязательным. Мы не можем удалить это предложение, так же мы не можем удалить столбец CLASS из списка столбцов.
Результат последнего запроса будет выглядеть примерно так:
CLASS | COUNT | AVG |
---|---|---|
2A | 12 | 13.5 |
2B | 9 | 13.9 |
3A | 11 | 14.6 |
3B | 12 | 14.4 |
... | ... | ... |
Заголовки "COUNT" и "AVG" не очень информативны. В простейшем случае вы можете обойти это, но лучше, если мы дадим им значимые имена с помощью псевдонимов:
SELECT
class,
COUNT(*) AS num_boys,
AVG(age) AS boys_avg_age
FROM students
WHERE sex = 'M'
GROUP BY class
Как вы помните из формального синтаксиса списка столбцов, ключевое слово AS не является обязательным.
Добавление большего не агрегированных (или точнее строчно зависимых) столбцов требуется добавления их в предложения GROUP BY тоже. Например, вы хотите видеть вышеуказанную информацию о девочках то же, и хотите видеть разницу между интернатами и студентами дневного отделения:
SELECT class, sex, boarding_type, COUNT(*) AS anumber, AVG(age) AS avg_age FROM students GROUP BY class, sex, boarding_type
CLASS | SEX | BOARDING_TYPE | ANUMBER | AVG_AGE |
---|---|---|---|---|
2A | F | BOARDING | 9 | 13.3 |
2A | F | DAY | 6 | 13.5 |
2A | M | BOARDING | 7 | 13.6 |
2A | M | DAY | 5 | 13.4 |
2B | F | BOARDING | 11 | 13.7 |
2B | F | DAY | 5 | 13.7 |
2B | M | BOARDING | 6 | 13.8 |
... | ... | ... | ... | ... |
Каждая строка в результирующем наборе соответствует одной конкретной комбинации переменных CLASS, SEX и BOARDING_TYPE. Агрегированные результаты — количество и средний возраст — приведены для каждой из конкретизированной группы отдельно. В результате запроса вы не можете увидеть обобщённые результаты для мальчиков отдельно или для студентов дневного отделения отдельно. Таким образом, вы должны найти компромисс. Чем больше вы добавляете неагрегатных столбцов, тем больше вы конкретизируете группы, и тем больше вы упускаете общую картину из виду. Конечно, вы все ещё можете получить "большие" агрегаты, с помощью отдельных запросов.
Так же, как и предложение WHERE ограничивает строки в наборе данных, теми которые удовлетворяют условию поиска, с той разницей, что предложение HAVING накладывает ограничения на агрегированные строки сгруппированного набора. Предложение HAVING не является обязательным и может быть использовано только в сочетании с предложением GROUP BY.
Условие(я) в предложении HAVING может ссылаться на:
Любой агрегированный столбец в списке выбора SELECT. Это наиболее широко используемый случай;
Любое агрегированное выражение, которое не находится в списке выбора SELECT, но разрешено в контексте запроса. Иногда это полезно;
Любой столбец в списке GROUP BY. Однако более эффективно фильтровать не агрегированные данные на более ранней стадии в предложении WHERE;
Любое выражение, значение которого не зависит от содержимого набора данных (например, константа или контекстная переменная). Это допустимо, но совершенно бессмысленно, потому что такое условие, не имеющее никакого отношения к самому набору данных, либо подавит весь набор, либо оставит его не тронутым.
Предложение HAVING не может содержать:
Не агрегированные выражения столбца, которые не находятся в списке GROUP BY;
Позицию столбца. Целое число в предложении HAVING – просто целое число;
Псевдонимы столбца – даже, если они появляются в предложении GROUP BY.
Перестроим наши ранние примеры. Мы можем использовать предложение HAVING для исключения малых групп студентов:
SELECT class, COUNT(*) AS num_boys, AVG(age) AS boys_avg_age FROM students WHERE sex = 'M' GROUP BY class HAVING COUNT(*) >= 5
Выберем только группы, которые имеют минимальный разброс по возрасту 1,2 года:
SELECT class, COUNT(*) AS num_boys, AVG(age) AS boys_avg_age FROM students WHERE sex = 'M' GROUP BY class HAVING MAX(age) - MIN(age) > 1.2
Обратите внимание, что если вас действительно интересует эта информация, то неплохо бы включить в список выбора min(age) и max(age) или выражение max(age) – min(age).
Следующий запрос отбирает только учеников 3 класса:
SELECT class, COUNT(*) AS num_boys, AVG(age) AS boys_avg_age FROM students WHERE sex = 'M' GROUP BY class HAVING class STARTING WITH '3'
Однако гораздо лучше переместить это условие в предложение WHERE:
SELECT class, COUNT(*) AS num_boys, AVG(age) AS boys_avg_age FROM students WHERE sex = 'M' AND class STARTING WITH '3' GROUP BY class
Предложение PLAN позволяет пользователю указать свой план выполнения запроса, который перекрывает тот план, который оптимизатор сгенерировал автоматически.
Синтаксис:
PLAN<plan-expr>
<plan-expr>
::= (<plan-item>
[,<plan-item>
...]) |<sorted-item>
|<joined-item>
|<merged-item>
<sorted-item>
::= SORT (<plan-item>
)<joined-item>
::= JOIN (<plan-item>
,<plan-item>
[,<plan-item>
...])<merged-item>
::= [SORT] MERGE (<sorted-item>
,<sorted-item>
[,<sorted-item>
...])<hash-item>
::= HASH (<plan-item>
,<plan-item>
[,<plan-item>
...])<plan-item>
::= <basic-item> | <plan-expr><basic-item>
::=<relation>
{ NATURAL | INDEX (<indexlist>
) | ORDERindex
[INDEX (<indexlist>
)] }<relation>
::=table
|view
[table
]<indexlist>
::=index
[,index
...]
Таблица 5.7. Параметры предложения PLAN
Параметр | Описание |
---|---|
table |
Имя таблицы или её алиас. |
view |
Имя представления. |
index |
Имя индекса. |
Каждый раз, когда пользователь отправляет запрос ядру Firebird, оптимизатор вычисляет стратегию извлечения данных. Большинство клиентов Firebird имеют возможность отобразить пользователю план извлечения данных. В собственном инструменте isql это делается с помощью команды SET PLAN ON. Если вы хотите только изучить план запроса без его выполнения, то вам необходимо ввести команду SET PLANONLY ON, после чего будут извлекаться планы запросов без их выполнения. Для возврата isql в режим выполнения запросов введите команду SET PLANONLY OFF.
В большинстве случаев, вы можете доверять тому, что Firebird выберет наиболее оптимальный план запроса. Однако если ваши запросы очень сложны и вам кажется, что они выполняются не эффективно, вам необходимо посмотреть план запроса и подумать можете ли вы улучшить его.
Простейшие планы состоят только из имени таблицы и следующим за ним метода извлечения. Например, для неотсортированной выборки из единственной таблицы без предложения WHERE:
SELECT * FROM students PLAN (students NATURAL)
Если есть предложение WHERE вы можете указать индекс, который будет использоваться при нахождении совпадений:
SELECT *
FROM students
WHERE class = '3C'
PLAN (students INDEX (ix_stud_class))
Директива INDEX может использоваться также для условий соединения (которые будут обсуждаться чуть позже). Она содержит список индексов, разделённых запятыми.
Директива ORDER определяет индекс, который используется при сортировке набора данных, если присутствуют предложения ORDER BY или GROUP BY:
SELECT * FROM students PLAN (students ORDER pk_students) ORDER BY id
Инструкции ORDER и INDEX могут быть объединены:
SELECT *
FROM students
WHERE class >= '3'
PLAN (students ORDER pk_students INDEX (ix_stud_class))
ORDER BY id
В инструкциях ORDER и INDEX разрешено указывать один и тот же индекс:
SELECT *
FROM students
WHERE class >= '3'
PLAN (students ORDER ix_stud_class INDEX (ix_stud_class))
ORDER BY class
Для сортировки наборов данных, когда невозможно использовать индекс (или вы хотите подавить его использование), уберите инструкцию ORDER и предварите выражение плана инструкцией SORT:
SELECT * FROM students PLAN SORT (students NATURAL) ORDER BY name
Или когда индекс используется для поиска:
SELECT *
FROM students
WHERE class >= '3'
PLAN SORT (students INDEX (ix_stud_class))
ORDER BY name
Обратите внимание, что инструкция SORT, в отличие от ORDER, находится за пределами скобок. Это отражает тот факт, что строки данных извлекаются неотсортированными и сортируются впоследствии.
При выборке из представления указывается само представление и участвующее в нем таблица. Например, если у вас есть представление FRESHMEN, которое выбирает только студентов первокурсников:
SELECT * FROM freshmen PLAN (freshmen students NATURAL)
Или, например:
SELECT *
FROM freshmen
WHERE id > 10
PLAN SORT (freshmen students INDEX (pk_students))
ORDER BY name DESC
Обратите внимание: если вы назначили псевдоним таблице или представлению, то в предложении PLAN необходимо использовать псевдоним, а не оригинальное имя.
Если вы делаете соединение, то вы можете указать индекс, который будет использоваться для сопоставления. Кроме того, вы должны использовать директиву JOIN для двух потоков в плане:
SELECT s.id, s.name, s.class, c.mentor FROM students s JOIN classes c ON c.name = s.class PLAN JOIN (s NATURAL, c INDEX (pk_classes))
То же самое соединение, отсортированное по индексированному столбцу:
SELECT s.id, s.name, s.class, c.mentor FROM students s JOIN classes c ON c.name = s.class PLAN JOIN (s ORDER pk_students, c INDEX (pk_classes)) ORDER BY s.id
И соединение, отсортированное не по индексированному столбцу:
SELECT s.id, s.name, s.class, c.mentor FROM students s JOIN classes c ON c.name = s.class PLAN SORT (JOIN (S NATURAL, c INDEX (pk_classes)))) ORDER BY s.name
Соединение с добавленным условием поиска:
SELECT s.id, s.name, s.class, c.mentor
FROM students s
JOIN classes c ON c.name = s.class
WHERE s.class <= '2'
PLAN SORT (JOIN (s INDEX (fk_student_class), c INDEX (pk_classes)))
ORDER BY s.name
То же самое, но используется левое внешнее соединение:
SELECT s.id, s.name, s.class, c.mentor
FROM classes c
LEFT JOIN students s ON c.name = s.class
WHERE s.class <= '2'
PLAN SORT (JOIN (c NATURAL, s INDEX (fk_student_class)))
ORDER BY s.name
Если нет доступных индексов для условия соединения (или вы не хотите его использовать), то возможно соединение потоков с помощью метода MERGE.
При выполнении соединения методом MERGE план должен сначала отсортировать оба потока по соединяемым столбцам и затем произвести слияние. Это достигается с помощью директив SORT (которую вы уже встречали) и MERGE используемую вместо JOIN.
SELECT * FROM students s JOIN classes c ON c.cookie = s.cookie PLAN MERGE (SORT (c NATURAL), SORT (s NATURAL))
Добавление предложения ORDER BY означает, что результат слияния также должен быть отсортирован:
SELECT * FROM students s JOIN classes c ON c.cookie = s.cookie PLAN SORT (MERGE (SORT (c NATURAL), SORT (s NATURAL))) ORDER BY c.name, s.id
И наконец, мы добавляем условие поиска на двух индексированных столбцах таблицы STUDENTS:
SELECT * FROM students s JOIN classes c ON c.cookie = s.cookie WHERE s.id < 10 AND s.class <= '2' PLAN SORT (MERGE (SORT (c NATURAL), SORT (s INDEX (pk_students, fk_student_class)))) ORDER BY c.name, s.id
Как следует из формального определения синтаксиса, JOIN и MERGE могут объединять в плане более двух потоков. Кроме того, каждое выражение плана может использоваться в качестве элемента в охватывающем плане. Это означает, что планы некоторых сложных запросов могут иметь различные уровни вложенности.
Наконец, вместо MERGE вы можете писать SORT MERGE. Поскольку это не имеет абсолютно никакого значения и может создать путаницу с "настоящей" директивой SORT (которая действительно имеет значение), то вероятно лучше придерживаться простой директивы MERGE.
Помимо плана для основного запроса вы можете указать план для каждого подзапроса. Например, следующий запрос с указанием планов будет абсолютно правильным.
SELECT * FROM COLOR WHERE EXISTS( SELECT * FROM HORSE WHERE HORSE.CODE_COLOR = COLOR.CODE_COLOR PLAN (HORSE INDEX (FK_HORSE_COLOR))) PLAN(COLOR NATURAL)
Предложение UNION объединяет два и более набора данных, тем самым увеличивая общее количество строк, но не столбцов. Наборы данных, принимающие участие в UNION, должны иметь одинаковое количество столбцов. Однако столбцы в соответствующих позициях не обязаны иметь один и тот же тип данных, они могут быть абсолютно не связанными.
По умолчанию, объединение подавляет дубликаты строк. UNION ALL отображает все строки, включая дубликаты. Необязательное ключевое слово DISTINCT делает поведение по умолчанию явным.
Синтаксис:
<union>
::=<individual-select>
UNION [DISTINCT | ALL]<individual-select>
[UNION [DISTINCT | ALL]<individual-select>
[...] [<union-wide-clauses>
]<individual-select>
::= SELECT [FIRSTm
] [SKIPn
] [DISTINCT | ALL]<columns>
FROMsource
[[AS]alias
] [<joins>
] [WHERE<condition>
] [GROUP BY<grouping-list>
[HAVING<aggregate-condition>
]] [PLAN<plan-expr>
]<union-wide-clauses>
::= [ORDER BY<ordering-list>
] [ROWSm
[TOn
]] [FOR UPDATE [OF<forupdate-columns>
]] [WITH LOCK] [INTO<PSQL-varlist>
]
Объединения получают имена столбцов из первого запроса на выборку. Если вы хотите дать псевдонимы объединяемым столбцам, то делайте это для списка столбцов в самом верхнем запросе на выборку. Псевдонимы в других участвующих в объединении выборках разрешены, и могут быть даже полезными, но они не будут распространяться на уровне объединения.
Если объединение имеет предложение ORDER BY, то единственно возможными элементами сортировки являются целочисленные литералы, указывающие на позиции столбцов, необязательно сопровождаемые ASC/DESC и/или NULLS FIRST/LAST директивами. Это так же означает, что вы не можете упорядочить объединение ничем, что не является столбцом объединения. (Однако вы можете завернуть его в производную таблицу, которая даст вам все обычные параметры сортировки.)
Объединения позволены в подзапросах любого вида и могут самостоятельно содержать подзапросы. Они также могут содержать соединения (joins), и могут принимать участие в соединениях, если завёрнуты в производную таблицу.
Этот запрос представляет информацию из различных музыкальных коллекций в одном наборе данных с помощью объединений:
SELECT id, title, artist, len, 'CD' AS medium FROM cds UNION SELECT id, title, artist, len, 'LP' FROM records UNION SELECT id, title, artist, len, 'MC' FROM cassettes ORDER BY 3, 2 -- artist, title
Если id, title, artist и length – единственные поля во всех участвующих таблицах, то запрос может быть записан так:
SELECT c.*, 'CD' AS medium FROM cds c UNION SELECT r.*, 'LP' FROM records r UNION SELECT c.*, 'MC' FROM cassettes c ORDER BY 3, 2 -- artist, title
Квалификация "звёзд" необходима здесь, потому что они не являются единственным элементом в списке столбцов. Заметьте, что псевдонимы "c" в первой и третьей выборке не кусают друг друга. Они не имеют контекста объединения, а лишь применяются к отдельным запросам на выборку.
Следующий запрос получает имена и телефонные номера переводчиков и корректоров. Те переводчики, которые также работают корректорами, будут отображены только один раз в результирующем наборе, если номера их телефонов одинаковые в обеих таблицах. Тот же результат может быть получен без ключевого слова DISTINCT. Если вместо ключевого слова DISTINCT, будет указано ключевое слово ALL, эти люди будут отображены дважды.
SELECT name, phone FROM translators UNION DISTINCT SELECT name, telephone FROM proofreaders
Пример использования UNION в подзапросе:
SELECT name, phone, hourly_rate FROM clowns WHERE hourly_rate < ALL (SELECT hourly_rate FROM jugglers UNION SELECT hourly_rate FROM acrobats) ORDER BY hourly_rate
Результат выборки данных при выполнении оператора SELECT по умолчанию никак не упорядочивается (хотя довольно часто происходит упорядочение в хронологическом порядке помещёния строк в таблицу операторами INSERT). Предложение ORDER BY позволяет задать необходимый порядок при выборке данных.
Синтаксис:
SELECT ... FROM ... ... ORDER BY<ordering-item>
[,<ordering-item>
...]<ordering-item>
::= {col-name
|col-alias
|col-position
|expression
} [COLLATEcollation-name
] [ASC[ENDING] | DESC[ENDING]] [NULLS {FIRST | LAST}]
Таблица 5.8. Параметры предложения ORDER BY
Параметр | Описание |
---|---|
col-name |
Полное имя столбца. |
col-alias |
Алиас (псевдоним) столбца. |
col-position |
Позиция столбца. |
expression |
Произвольное выражение. |
collation-name |
Имя сопоставления (порядка сортировки). |
В предложении через запятую перечисляются столбцы, по которым нужно упорядочить результирующий набор данных. Можно задавать имя столбца, псевдоним, присвоенный столбцу в списке выбора при помощи ключевого слова AS, или порядковый номер столбца в списке выбора. В одном предложении можно для разных столбцов смешивать форму записи. Например, один столбец в списке сортировки может быть задан своим именем, а другой порядковым номером.
Если вы сортируете по позиции столбца или его алиасу, то выражение соответствующее этой позиции (алиасу) будет скопировано из списка выборки SELECT. Это касается и подзапросов, таким образом, подзапрос будет выполняться, по крайней мере, два раза.
В случае сортировки по номеру столбца для запроса вида "SELECT *" сервер раскрывает звёздочку (*) для определения сортируемых столбцов. Однако использование данной особенности в ваших запросах является плохой практикой.
Ключевое слово ASCENDING задаёт упорядочение по возрастанию значений. Допустимо сокращение ASC. Применяется по умолчанию.
Ключевое слово DESCENDING задаёт упорядочение по убыванию значений. Допустимо сокращение DESC.
В одном предложении упорядочение по одному столбцу может идти по возрастанию значений, а по другому — по убыванию.
Ключевое слово COLLATE позволяет задать порядок сортировки строкового столбца, если нужен порядок, отличный от того, который был установлен для этого столбца (явно при описании столбца или по умолчанию, принятому для соответствующего набора символов).
Ключевое слово NULLS определяет, где в отсортированном наборе данных будут находиться значения NULL соответствующего столбца – в начале выборки (FIRST) или в конце (LAST). По умолчанию принимается NULLS FIRST.
Части выборок SELECT, участвующих в объединении UNION, не могут быть отсортированы с использованием предложения ORDER BY. Однако вы можете достичь желаемого результата с использованием производных таблиц или общих табличных выражений. Предложение ORDER BY, записанное последним в объединении, будет применено ко всей выборке в целом, а не к последней его части. Для объединений, единственно возможными элементами сортировки являются целочисленные литералы, указывающие на позиции столбцов, необязательно сопровождаемые ASC / DESC и/или NULLS FIRST / LAST директивами.
В описанном ниже запросе выборка будет отсортирована по возрастанию по столбцам RDB$CHARACTER_SET_ID, RDB$COLLATION_ID таблицы DB$COLLATIONS:
SELECT RDB$CHARACTER_SET_ID AS CHARSET_ID, RDB$COLLATION_ID AS COLL_ID, RDB$COLLATION_NAME AS NAME FROM RDB$COLLATIONS ORDER BY RDB$CHARACTER_SET_ID, RDB$COLLATION_ID
То же самое, но сортировка производится по псевдонимам столбцов:
SELECT RDB$CHARACTER_SET_ID AS CHARSET_ID, RDB$COLLATION_ID AS COLL_ID, RDB$COLLATION_NAME AS NAME FROM RDB$COLLATIONS ORDER BY CHARSET_ID, COLL_ID
В следующем запросе производится сортировка, по номерам столбцов:
SELECT RDB$CHARACTER_SET_ID AS CHARSET_ID, RDB$COLLATION_ID AS COLL_ID, RDB$COLLATION_NAME AS NAME FROM RDB$COLLATIONS ORDER BY 1, 2
Как было выше сказано, такая сортировка тоже допустима, но не рекомендуется:
SELECT * FROM RDB$COLLATIONS ORDER BY 3, 2
В данном запросе сортировка происходит по второму столбцу таблицы BOOKS:
SELECT
BOOKS.*,
FILMS.DIRECTOR
FROM BOOKS, FILMS
ORDER BY 2
Обратите внимание на то, что выражения, результатом вычисления которых должны быть целые неотрицательные числа, будут интерпретироваться как номер столбца и вызовут исключение, если они не будут в диапазоне от 1 до числа столбцов.
Пример:
SELECT X, Y, NOTE FROM PAIRS ORDER BY X+Y DESC
Примечания:
Число, возвращаемое функцией или процедурой из UDF или хранимой процедуры, непредсказуемо, независимо от того, определена сортировка самим выражением или номером столбца;
Только неотрицательные целые числа интерпретируются как номер столбца. Целое число, полученное однократным вычислением выражения или заменой параметра, запоминается как целочисленная постоянная величина, так как это значение одинаково для всех строк.
Сортировка по убыванию значений столбца PROCESS_TIME с размещёнием значений NULL в начале выборки:
SELECT * FROM MSG ORDER BY PROCESS_TIME DESC NULLS FIRST
Сортировка выборки полученной объединением выборок из двух запросов. Выборка сортируется по убыванию значений второго столбца с размещёнием NULL значений в конце списка и возрастанием значений первого столбца с размещёнием NULL значений в начале списка.
SELECT DOC_NUMBER, DOC_DATE FROM PAYORDER UNION ALL SELECT DOC_NUMBER, DOC_DATE FROM BUDGORDER ORDER BY 2 DESC NULLS LAST, 1 ASC NULLS FIRST
Назначение: Получение части строк из упорядоченного набора.
Синтаксис:
SELECT ... FROM ... ... ROWSm
[TOn
]
Предложение ROWS было введено для совместимости с Interbase 6.5 и выше.
В отличие от FIRST и SKIP, выражение ROWS принимает все типы целочисленных (integer) выражений в качестве аргумента – без скобок! Конечно, скобки могут требоваться для правильных вычислений внутри выражения, и вложенный запрос также должен быть обернут в скобки.
Нумерация записей в наборе данных начинается с 1.
И FIRST/SKIP, и ROWS могут быть использованы без выражения ORDER BY, хотя это редко имеет смысл, за исключением случая, когда необходимо быстро взглянуть на данные таблицы – получаемые строки при этом будут чаще всего в случайном порядке. В этом случае запрос вроде "SELECT * FROM TABLE1 ROWS 20" вернёт 20 первых записей, а не целую таблицу (которая может очень большой).
Вызов ROWS m
приведёт к возвращению первых
m
записей из набора данных.
Если m
больше общего числа записей в
возвращаемом наборе данных, то будет возвращён весь набор данных;
Если m
= 0, то будет возвращён пустой
набор данных;
Если m
< 0, выдаётся ошибка.
В случае указания ROWS m
TO
n
, то будут возвращены записи с
m
по n
из набора
данных.
Если m
больше общего количества строк в
наборе данных и n
>=
m
, то будет возвращён пустой набор
данных;
Если число m
не превышает общего
количества строк в наборе данных, а n
превышает, то выборка ограничивается строками, начиная с
m
до конца набора данных;
Если m
< 1 и
n
< 1, то оператор SELECT выдаст
ошибку;
Если n
= m
-1, то будет возвращён пустой набор данных;
Если n
<
m
-1, то оператор SELECT выдаст
ошибку.
В сущности, ROWS заменяет собой нестандартные выражения FIRST и SKIP, за исключением единственного случая, когда указывается только SKIP, т.е. когда возвращается весь набор данных за исключением пропуска указанного числа записей с начала.
Для того, что реализовать такое поведение с помощью ROWS, необходимо указать второй аргумент, заведомо больший, чем размер возвращаемого набора данных. Или запросить число записей в возвращаемом наборе через подзапрос.
Нельзя использовать ROWS вместе с FIRST/SKIP в одном и том же операторе SELECT, но можно использовать разный синтаксис в разных подзапросах.
При использовании ROWS с выражением UNION, он будет применяться к объединённому набору данных, и должен быть помещён после последнего SELECT.
При необходимости ограничить возвращаемые наборы данных одного или нескольких операторов SELECT внутри UNION, можно воспользоваться следующими вариантами:
Использовать FIRST/SKIP в этих операторах SELECT. Необходимо помнить, что нельзя локально использовать выражение ORDER BY в SELECT внутри UNION – только глобально, ко всему суммарному набору данных;
Преобразовать SELECT в производные таблицы с выражениями ROWS.
Ниже приведены примеры, ранее использованные для демонстрации FIRST/SKIP.
Следующий запрос вернёт первые 10 имён из таблицы PEOPLE (имена также будут отсортированы, см. ORDER BY).
SELECT id, name FROM People ORDER BY name ASC ROWS 1 TO 10
или его эквивалент
SELECT id, name
FROM People
ORDER BY name ASC
ROWS 10
Следующий запрос вернёт все записи из таблицы PEOPLE, за исключением первых 10 имён:
SELECT id, name
FROM People
ORDER BY name ASC
ROWS 11 TO (SELECT COUNT(*) FROM People)
А этот запрос вернёт последние 10 записей (обратите внимание на скобки):
SELECT id, name
FROM People
ORDER BY name ASC
ROWS (SELECT COUNT(*) - 9 FROM People)
TO (SELECT COUNT(*) FROM People)
Этот запрос вернёт строки 81-100 из таблицы PEOPLE:
SELECT id, name FROM People ORDER BY name ASC ROWS 81 TO 100
См. также: FIRST, SKIP.
Синтаксис:
SELECT ... FROMsingle_table
[WHERE ...] [FOR UPDATE [OF<column-names>
]]
Предложение FOR UPDATE не делает то, что от него ожидается. В настоящее время единственный эффект от его использования заключается лишь в отключении упреждающей выборки в буфер.
Это, вероятно, изменится в будущем: план состоит в том, чтобы проверять курсоры, отмеченные как FOR UPDATE, действительно ли они обновляемые, и отклонять позиционированные обновления и удаления для курсоров, оцененных как необновляемый.
Предложение OF не делает ничего вообще.
Назначение: Пессимистическая блокировка.
Опция WITH LOCK, обеспечивает возможность ограниченной явной пессимистической блокировки для осторожного использования в затронутых наборах строк:
крайне малой выборки (в идеале из одной строки) и
при контроле из приложения.
Пессимистическая блокировка редко требуется при работе с Firebird. Эту функцию можно использовать только хорошо понимая её.
Требуется хорошее знание различных уровней изоляции и других параметров транзакций прежде чем использовать явную блокировку в вашем приложении.
Синтаксис:
SELECT ... FROMsingle_table
[WHERE ...] [FOR UPDATE [OF<column-names>
]] WITH LOCK
При успешном выполнении предложения WITH LOCK будут заблокированы выбранные строки данных и таким образом запрещён доступ на их изменение в рамках других транзакций до момента завершения вашей транзакции.
Предложение WITH LOCK доступно только для выборки данных (SELECT) из одной таблицы. Предложение WITH LOCK нельзя использовать:
в подзапросах;
в запросах с объединением нескольких таблиц (JOIN);
с оператором DISTINCT, предложением GROUP BY и при использовании любых агрегатных функций;
при работе с представлениями;
при выборке данных из селективных хранимых процедур;
при работе с внешними таблицами.
Сервер, в свою очередь, для каждой записи, подпадающей под явную блокировку, возвращает версию записи, которая является в настоящее время подтверждённой (актуальной), независимо от состояния базы данных, когда был выполнен оператор выборки данных, или исключение при попытке обновления заблокированной записи.
Ожидаемое поведение и сообщения о конфликте зависят от параметров транзакции, определённых в TPB (Transaction Parameters Block):
Таблица 5.10. Влияние параметров TPB на явную блокировку
Режим TPB | Поведение |
---|---|
isc_tpb_consistency | Явные блокировки переопределяются неявными или явными блокировками табличного уровня и игнорируются. |
isc_tpb_concurrency + isc_tpb_nowait |
При подтверждении изменения записи в транзакции, стартовавшей после транзакции, запустившей явную блокировку, немедленно возникает исключение конфликта обновления. |
isc_tpb_concurrency + isc_tpb_wait |
При подтверждении изменения записи в транзакции, стартовавшей после транзакции, запустившей явную блокировку, немедленно возникает исключение конфликта обновления. Если в активной транзакции идёт редактирование записи (с использованием явной блокировки или нормальной оптимистической блокировкой записи), то транзакция, делающая попытку явной блокировки, ожидает окончания транзакции блокирования и, после её завершения, снова пытается получить блокировку записи. Это означает, что при изменении версии записи и подтверждении транзакции с блокировкой возникает исключение конфликта обновления. |
isc_tpb_read_committed + isc_tpb_nowait |
Если есть активная транзакция, редактирующая запись (с использованием явной блокировки или нормальной оптимистической блокировкой записи), то сразу же возникает исключение конфликта обновления. |
isc_tpb_read_committed + isc_tpb_wait |
Если в активной транзакции идёт редактирование записи (с использованием явной блокировки или нормальной оптимистической блокировкой записи), то транзакция, делающая попытку явной блокировки, ожидает окончания транзакции блокирования и, после её завершения, снова пытается получить блокировку записи. Для этого режима TPB никогда не возникает конфликта обновления. |
Если предложение FOR UPDATE предшествует предложению WITH LOCK, то буферизация выборки не используется. Таким образом, блокировка применяется к каждой строке, одна за другой, по мере извлечения записей. Это делает возможным ситуацию, в которой успешная блокировка данных перестаёт работать при достижении в выборке строки, заблокированной другой транзакцией.
Кроме того, некоторые компоненты доступа позволяют установить размер буфера выборки и уменьшить его до 1 записи. Это позволяет вам заблокировать и редактировать строку до выборки и блокировки следующей или обрабатывать ошибки, не отменяя действий вашей транзакции.
Опциональное предложение «OF <column-names>» не делает ничего вообще.
Попытка редактирования записи с помощью оператора UPDATE, заблокированной другой транзакцией, приводит к вызову исключения конфликта обновления или ожиданию завершения блокирующей транзакции – в зависимости от режима TPB. Поведение сервера здесь такое же, как если бы эта запись уже была изменена блокирующей транзакцией.
Нет никаких специальных кодов gdscode, возвращаемых для конфликтов обновления, связанных с пессимистической блокировкой.
Сервер гарантирует, что все записи, возвращённые явным оператором блокировки, фактически заблокированы и действительно соответствуют условиям поиска, заданным в операторе WHERE, если эти условия не зависят ни от каких других таблиц, не имеется операторов соединения, подзапросов и т.п. Это также гарантирует то, что строки, не попадающие под условия поиска, не будут заблокированы. Это не даёт гарантии, что нет строк, которые попадают под условия поиска, и не заблокированы.
Такая ситуация может возникнуть, если в другой, параллельной транзакции подтверждаются изменения в процессе выполнения текущего оператора блокировки.
Сервер блокирует строки по мере их выборки. Это имеет важные последствия, если вы блокируете сразу несколько строк. Многие методы доступа к базам данных Firebird по умолчанию используют для выборки данных пакеты из нескольких сотен строк (так называемый "буфер выборки"). Большинство компонентов доступа к данным не выделяют строки, содержащиеся в последнем принятом пакете, и для которых произошёл конфликт обновления.
Откат неявной или явной точки сохранения отменяет блокировку записей, которые изменялись в рамках её действий, но ожидающие окончания блокировки транзакции при этом не уведомляются. Приложения не должны зависеть от такого поведения, поскольку в будущем оно может быть изменено;
Хотя явные блокировки могут использоваться для предотвращения и/или обработки необычных ошибок конфликтов обновления, объем ошибок обновления (deadlock) вырастет, если вы тщательно не разработаете свою стратегию блокировки и не будете ей строго управлять;
Большинство приложений не требуют явной блокировки записей. Основными целями явной блокировки являются: 1) предотвращение дорогостоящей обработки ошибок конфликта обновления в сильно загруженных приложениях и 2) для поддержания целостности объектов, отображаемых из реляционной базы данных в кластеризируемой среде. Если использование вами явной блокировки не подпадает под одну из этих двух категорий, то это является неправильным способом решения задач в Firebird;
Явная блокировка — это расширенная функция; не злоупотребляйте её использованием! В то время как явная блокировка может быть очень важной для веб-сайтов, обрабатывающих тысячи параллельных пишущих транзакций или для систем типа ERP/CRM, работающих в крупных корпорациях, большинство прикладных программ не требуют её использования.
Назначение: Передача результатов SELECT в переменные.
Доступно в: PSQL.
Синтаксис:
SELECT [...]<column-list>
FROM ... [...] [INTO<variable-list>
]<variable-list>
::= [:]psqlvar
[, [:]psqlvar
...]
В PSQL (хранимых процедурах, триггерах и др.) результаты выборки команды SELECT могут быть построчно загружены в локальные переменные (число, порядок и типы локальных переменных должны соответствовать полям SELECT). Часто такая загрузка – единственный способ что-то сделать с возвращаемыми значениями.
Простой оператор SELECT может быть использован в PSQL, только если он возвращает не более одной строки, то есть, если это запрос типа singleton (одиночка). Для запросов, возвращающих несколько строк, PSQL предлагает использовать оператор FOR SELECT.
В случае, когда запрос не возвращает данных (ноль строк), значения переменных
в списке INTO <variable-list>
не
изменяется.
Также, PSQL поддерживает оператор DECLARE CURSOR, который связывает именованный курсор с определенной командой SELECT — и этот курсор впоследствии может быть использован для навигации по возвращаемому набору данных.
В PSQL выражение INTO должно появляться в самом конце команды SELECT.
В PSQL двоеточие перед именами переменных является опциональным.
В PSQL, можно присвоить значения min_amt, avg_amt и max_amt заранее объявленным переменным или выходным параметрам:
SELECT
MIN(amount),
AVG(CAST(amount AS float)),
MAX(amount)
FROM orders
WHERE artno = 372218
INTO min_amt,
avg_amt,
max_amt;
В данном запросе CAST служит для корректного вычисления среднего значения. Если не привести значение к float, то среднее значение будет обрезано до ближайшего целого значения.
В триггере:
SELECT LIST(name, ', ')
FROM persons p
WHERE p.id IN (new.father, new.mother)
INTO new.parentnames;
Общие табличные выражения (Common Table Expressions), сокращённо CTE, описаны как виртуальные таблицы или представления, определённые в преамбуле основного запроса, которые участвуют в основном запросе. Основной запрос может ссылаться на любое CTE из определённых в преамбуле, как и при выборке данных из обычных таблиц или представлений. CTE могут быть рекурсивными, т.е. ссылающимися сами на себя, но не могут быть вложенными.
Синтаксис:
<cte-construct>
::=<cte-defs>
<main-query>
<cte-defs>
::= WITH [RECURSIVE]<cte>
[,<cte>
...]<cte>
::=name
[(<column-list>
)] AS (<cte-stmt>
)<column-list>
::=column-alias
[,column-alias
...]
Таблица 5.11. Параметры CTE
Параметр | Описание |
---|---|
cte-stmt |
Любой оператор SELECT или UNION. |
main-query |
Основной оператор SELECT, который может ссылаться на любое CTE из найденных в преамбуле. |
name |
Алиас табличного выражения. |
column-alias |
Алиас столбца табличного выражения. |
Примеры:
Пример 5.1. Запрос с использованием CTE
WITH DEPT_YEAR_BUDGET AS ( SELECT FISCAL_YEAR, DEPT_NO, SUM(PROJECTED_BUDGET) BUDGET FROM PROJ_DEPT_BUDGET GROUP BY FISCAL_YEAR, DEPT_NO ) SELECT D.DEPT_NO, D.DEPARTMENT, DYB_2008.BUDGET BUDGET_08, DYB_2009.BUDGET AS BUDGET_09 FROM DEPARTMENT D LEFT JOIN DEPT_YEAR_BUDGET DYB_2008 ON D.DEPT_NO = DYB_2008.DEPT_NO AND DYB_2008.FISCAL_YEAR = 2008 LEFT JOIN DEPT_YEAR_BUDGET DYB_2009 ON D.DEPT_NO = DYB_2009.DEPT_NO AND DYB_2009.FISCAL_YEAR = 2009 WHERE EXISTS (SELECT * FROM PROJ_DEPT_BUDGET B WHERE D.DEPT_NO = B.DEPT_NO)
Определение CTE может содержать любой правильный оператор SELECT, если он не содержит преамбулы "WITH ..." (операторы WITH не могут быть вложенными);
CTE могут использовать друг друга, но ссылки не должны иметь циклов;
CTE могут быть использованы в любой части главного запроса или другого табличного выражения и сколько угодно раз;
Основной запрос может ссылаться на CTE несколько раз, но с разными алиасами;
CTE могут быть использованы в операторах INSERT, UPDATE и DELETE как подзапросы;
До Firebird 2.5.8 если CTE объявлен, то он должен быть обязательно
использован, в противном случае возникает ошибка "CTE
<cte>
is not used in query".
Начиная с Firebird 2.5.8 вместо ошибки выдаётся предупреждение;
CTE могут быть использованы и в PSQL (FOR WITH ... SELECT ... INTO ...):
FOR
WITH MY_RIVERS AS (
SELECT *
FROM RIVERS
WHERE OWNER = 'me')
SELECT
NAME,
LENGTH
FROM MY_RIVERS
INTO :RNAME,
:RLEN
DO
BEGIN
...
END
Рекурсивное (ссылающееся само на себя) CTE это ОБЪЕДИНЕНИЕ, у которого должен быть, по крайней мере, один не рекурсивный элемент, к которому привязываются остальные элементы объединения. Не рекурсивный элемент помещается в CTE первым. Рекурсивные члены отделяются от не рекурсивных и друг от друга с помощью UNION ALL. Объединение не рекурсивных элементов может быть любого типа.
Рекурсивное CTE требует наличия ключевого слова RECURSIVE справа от WITH. Каждый рекурсивный член объединения может сослаться на себя только один раз и это должно быть сделано в предложении FROM.
Главным преимуществом рекурсивных CTE является то, что они используют гораздо меньше памяти и процессорного времени, чем эквивалентные рекурсивные хранимые процедуры.
Выполнение рекурсивного CTE с точки зрения сервера Firebird можно описать следующим образом:
Сервер начинает выполнение с не рекурсивного члена;
Для каждой выбранной строки из нерекурсивного части выполняется каждый рекурсивный член один за другим, используя текущие значения из предыдущей итерации как параметры;
Если во время выполнения экземпляр рекурсивного элемента не выдаёт строк, цикл выполнения переходит на предыдущий уровень и получает следующую строку от внешнего для него набора данных.
Важно отметить, что если СТЕ объявлена, то где-то ниже она обязательно должна быть использована, иначе будет ошибка вида «CTE "AAA" is not used in query».
Примеры:
Пример 5.2. Рекурсивное CTE
WITH RECURSIVE DEPT_YEAR_BUDGET AS ( SELECT FISCAL_YEAR, DEPT_NO, SUM(PROJECTED_BUDGET) BUDGET FROM PROJ_DEPT_BUDGET GROUP BY FISCAL_YEAR, DEPT_NO ), DEPT_TREE AS ( SELECT DEPT_NO, HEAD_DEPT, DEPARTMENT, CAST('' AS VARCHAR(255)) AS INDENT FROM DEPARTMENT WHERE HEAD_DEPT IS NULL UNION ALL SELECT D.DEPT_NO, D.HEAD_DEPT, D.DEPARTMENT, H.INDENT || ' ' FROM DEPARTMENT D JOIN DEPT_TREE H ON H.HEAD_DEPT = D.DEPT_NO ) SELECT D.DEPT_NO, D.INDENT || D.DEPARTMENT DEPARTMENT, DYB_2008.BUDGET AS BUDGET_08, DYB_2009.BUDGET AS BUDGET_09 FROM DEPT_TREE D LEFT JOIN DEPT_YEAR_BUDGET DYB_2008 ON (D.DEPT_NO = DYB_2008.DEPT_NO) AND (DYB_2008.FISCAL_YEAR = 2008) LEFT JOIN DEPT_YEAR_BUDGET DYB_2009 ON (D.DEPT_NO = DYB_2009.DEPT_NO) AND (DYB_2009.FISCAL_YEAR = 2009)
Следующий пример выводит родословную лошади. Основное отличие состоит в том, что рекурсия идёт сразу по двум веткам дерева родословной.
WITH RECURSIVE PEDIGREE ( CODE_HORSE, CODE_FATHER, CODE_MOTHER, NAME, MARK, DEPTH) AS (SELECT HORSE.CODE_HORSE, HORSE.CODE_FATHER, HORSE.CODE_MOTHER, HORSE.NAME, CAST('' AS VARCHAR(80)), 0 FROM HORSE WHERE HORSE.CODE_HORSE = :CODE_HORSE UNION ALL SELECT HORSE.CODE_HORSE, HORSE.CODE_FATHER, HORSE.CODE_MOTHER, HORSE.NAME, 'F' || PEDIGREE.MARK, PEDIGREE.DEPTH + 1 FROM HORSE JOIN PEDIGREE ON HORSE.CODE_HORSE = PEDIGREE.CODE_FATHER WHERE –- ограничение глубины рекурсии PEDIGREE.DEPTH < :MAX_DEPTH UNION ALL SELECT HORSE.CODE_HORSE, HORSE.CODE_FATHER, HORSE.CODE_MOTHER, HORSE.NAME, 'M' || PEDIGREE.MARK, PEDIGREE.DEPTH + 1 FROM HORSE JOIN PEDIGREE ON HORSE.CODE_HORSE = PEDIGREE.CODE_MOTHER WHERE –- ограничение глубины рекурсии PEDIGREE.DEPTH < :MAX_DEPTH ) SELECT CODE_HORSE, NAME, MARK, DEPTH FROM PEDIGREE
Примечания для рекурсивного CTE:
В рекурсивных членах объединения не разрешается использовать агрегаты (DISTINCT, GROUP BY, HAVING) и агрегатные функции (SUM, COUNT, MAX и т.п.);
Рекурсивная ссылка не может быть участником внешнего объединения OUTER JOIN;
Максимальная глубина рекурсии составляет 1024;
Рекурсивный член не может быть представлен в виде производной таблицы.
Назначение: Вставка данных в таблицу.
Доступно в: DSQL, ESQL, PSQL.
Синтаксис:
INSERT INTOtarget
{DEFAULT VALUES | [(<column_list>
)]<value_source>
} [RETURNING<returning_list>
[INTO<variables>
]]<column_list>
::=colname
[,colname
...]<value_source>
::= VALUES (<value_list>
) |<select_stmt>
<value_list>
::=value
[,value
...]<returning_list>
::=ret_value
[,ret_value
...]<variables>
::= [:]varname
[, [:]varname
...]
Таблица 5.12. Параметры оператора INSERT
Параметр | Описание |
---|---|
target |
Имя таблицы или представления, в которую происходит вставка новой записи или записей. |
colname |
Столбец таблицы или представления. |
value |
Выражение, значение которого используется для вставки в таблицу. |
ret_value |
Выражение, возвращаемое в предложении RETURNING. |
varname |
Имя PSQL переменной. |
Оператор INSERT добавляет строки в таблицу, или в одну или более таблиц представления. Если значения столбцов указаны в разделе VALUES, то будет вставлена одна строка. Значения столбцов также могут быть получены из оператора SELECT, в этом случае может быть вставлено от нуля и более строк. В случае DEFAULT VALUES, значения можно не указывать, и вставлена будет одна строка.
Один столбец не может быть указан более одного раза в списке столбцов;
При возвращении значений столбцов вставленной записи с помощью INTO в
контекстные переменные NEW.columnname
в
триггерах не должен использоваться префикс двоеточия (":").
В списке VALUES должны быть указаны значения для всех столбцов в списке столбцов в том же порядке и совместимые по типу. Если список столбцов отсутствует, то значения должны быть указаны для каждого столбца таблицы или представления (исключая вычисляемые столбцы).
Вводный синтаксис даёт возможность определить набор символов для значений строковых констант (литералов). Вводный синтаксис работаёт только с литералами строк: он не может быть применён к строковым переменным, параметрам, ссылкам на столбцы или значения, выражениям.
Примеры:
INSERT INTO cars (make, model, byyear) VALUES ('Ford', 'T', 1908); INSERT INTO cars VALUES ('Ford', 'T', 1908, 'USA', 850); -- обратите внимание на префикс '_' INSERT INTO People VALUES (_ISO8859_1 'Hans-Jörg Schäfer');
В этом случае выходные столбцы оператора SELECT, должны предоставить значения для каждого целевого столбца в списке столбцов, в том же порядке и совместимого типа. Если список столбцов отсутствует, то значения должны быть предоставлены для каждого столбца таблицы или представления (исключая вычисляемые столбцы).
Примеры:
INSERT INTO cars (make, model, byyear) SELECT make, model, byyear FROM new_cars; INSERT INTO cars SELECT * FROM new_cars; INSERT INTO Members (number, name) SELECT number, name FROM NewMembers WHERE Accepted = 1 UNION ALL SELECT number, name FROM SuspendedMembers WHERE Vindicated = 1 INSERT INTO numbers(num) WITH RECURSIVE r(n) AS ( SELECT 1 FROM rdb$database UNION ALL SELECT n+1 FROM r where n < 100 ) SELECT n FROM r
Конечно, имена столбцов в таблице источнике не обязательно должны быть такими же, как и в таблице приёмнике.
Любой тип оператора SELECT разрешён, пока его выходные столбцы точно соответствуют столбцам вставки по числу и типу. Типы не должны быть точно такими же, но они должны быть совместимыми по присваиванию.
В СУБД Firebird, вплоть до этой версии, необходимо знать об особенности реализации, которая проявляется в запросах в стиле, который применяется для создания дубликатов строк в той же таблице. Например, запрос
INSERT INTO T SELECT * FROM T
приведёт к «бесконечному циклу вставки», постоянно выбирая строки и вставляя их снова и снова до тех пор, пока система не исчерпает доступное пространство.
Эта особенность проявляется во всех DML операторах изменяющих данные и приводит к различным негативным эффектам. Это происходит потому, что DML операторы используют неявные курсоры для выполнения операций. Таким образом, наш предыдущий пример работает следующим образом:
FOR SELECT<values>
FROM T INTO<tmp_vars>
DO INSERT INTO T VALUES (<tmp_vars>
)
Такая реализация приводит к поведению, которое не согласуется с SQL стандартом. В Firebird 3.0 эта ошибка исправлена.
Предложение DEFAULT VALUES позволяет вставлять записи без указания значений вообще, ни непосредственно (в предложении VALUES), ни из оператора SELECT. Это возможно, только если для каждого NOT NULL поля и полей, на которые наложены другие ограничения, или имеются допустимые объявленные значения по умолчанию, или эти значения устанавливаются в BEFORE INSERT триггере.
Примеры:
INSERT INTO journal DEFAULT VALUES RETURNING entry_id
Оператор INSERT вставляющий только одну строку может включать необязательное предложение RETURNING для возврата значений из вставленной строки. Если предложение указано, то оно может содержать любые столбцы, указанные в операторе, или другие столбцы и выражения. Возвращаемые значения содержат все изменения, произведённые в триггерах BEFORE.
В DSQL, оператор с RETURNING всегда возвращает только одну строку. Если указано предложение RETURNING, и обнаружено более одной совпадающей строки, выдаётся сообщение об ошибке. Это поведение может быть изменено в последующих версиях Firebird.
Примеры:
Пример 5.3. Использование предложения RETURNING в операторе INSERT
INSERT INTO Scholars ( firstname, lastname, address, phone, email) VALUES ( 'Henry', 'Higgins', '27A Wimpole Street', '3231212', NULL) RETURNING lastname, fullname, id; INSERT INTO Dumbbells (first_name, last_name, iq) SELECT fname, lname, iq FROM Friends ORDER BY iq ROWS 1 RETURNING id, first_name, iq INTO :id, :fname, :iq;
Замечания:
Предложение RETURNING поддерживается только для INSERT .. VALUES и одиночных INSERT .. SELECT.
В DSQL оператор с использованием RETURNING всегда возвращает ровно одну строку. Если запись не была вставлена на самом деле, то все поля в возвращаемой строке будут меть значения NULL. Это поведение может быть изменено позже. В PSQL, если ни одна строка не вставлена, то ничего не возвращается и все целевые переменные сохраняют свои прежние значения.
Вставка в столбцы BLOB только возможна при следующих обстоятельствах:
Клиентское приложение вставляет BLOB посредством Firebird API. В этом случае все зависит от приложения, и не рассматривается в этом руководстве;
Длина строкового литерала не может превышать 32767 байт.
Если источником данных является столбец BLOB или выражение, возвращающее BLOB.
Назначение: Обновление данных в таблице.
Доступно в: DSQL, ESQL, PSQL.
Синтаксис:
UPDATEtarget
[[AS]alias
] SETcol
=newval
[,col
=newval
...] [WHERE {search-conditions
| CURRENT OFcursorname
}] [PLANplan_items
] [ORDER BYsort_items
] [ROWSm
[TOn
]] [RETURNING<returning_list>
[INTO<variables>
]]<returning_list>
::=ret_value
[,ret_value
...]<variables>
::= [:]varname
[, [:]varname
...]
Таблица 5.13. Параметры оператора UPDATE
Параметр | Описание |
---|---|
target |
Имя таблицы или представления, в которой происходит обновление записей. |
alias |
Псевдоним таблицы или представления. |
col |
Столбец таблицы или представления. |
newval |
Новые значения обновляемых столбцов в таблице (представлении). |
search-conditions |
Условие поиска, ограничивающее набор обновляемых строк. |
cursorname |
Имя курсора, по которому позиционируется обновляемая запись. |
plan_items |
Предложение плана. |
sort_items |
Предложение сортировки. |
m ,
n |
Целочисленные выражения для ограничения количества обновляемых строк. |
ret_value |
Выражение, возвращаемое в предложении RETURNING. |
varname |
Имя PSQL переменной. |
Изменяет значения в одной таблице или в большем количестве таблиц в представлении.
Если вы назначаете псевдоним таблице или представлению, вы обязаны использовать псевдоним для уточнения столбцов таблицы.
Изменяемые столбцы указываются в предложении SET. Столбцы и их значения перечисляются через запятую. Слева имя столбца, и справа значение или выражение.
Разрешено использовать имена столбцов в выражениях справа. При этом использоваться будет всегда старое значение столбца, даже если присваивание этому столбцу уже произошло ранее в перечислении SET. Один столбец может быть использован только один раз в конструкции SET.
Пример:
Данные в таблице TSET:
A B ---- 1 0 2 0
После выполнения оператора
update tset set a = 5, b = a
A B ---- 5 1 5 2
Обратите внимание, что старые значения (1 и 2) используются для обновления столбца b, даже после того как столбцу a были назначено новое значение (5).
Так было не всегда. До версии 2.5, столбцы сразу получали новые значения. Это являлось нестандартным поведением, и поэтому было изменено в версии 2.5.
Однако, для восстановления совместимости со старыми версиями в
firebird.conf
существует параметр
OldSetClauseSemantics
, который, будучи установленным
в 1, восстанавливает старое поведение. Этот параметр в будущем будет
удален.
Предложение WHERE ограничивает набор обновляемых записей заданным условием, или – в PSQL – текущей строкой именованного курсора, если указано предложение WHERE CURRENT OF.
Предложение WHERE CURRENT OF используется только в PSQL, т.к. в DSQL нет оператора DSQL для создания курсора.
Строковые литералы могут предваряться именем набора символов, для того чтобы Firebird понимал, как интерпретировать данные.
Примеры:
UPDATE addresses SET city = 'Saint Petersburg', citycode = 'PET' WHERE city = 'Leningrad'; UPDATE employees SET salary = 2.5 * salary WHERE title = 'CEO'; UPDATE People SET name = _ISO8859_1 'Hans-Jörg Schäfer' -- обратите внимание на префикс '_' WHERE id = 53662; UPDATE employee e SET salary = salary * 1.05 WHERE EXISTS( SELECT * FROM employee_project ep WHERE e.emp_no = ep.emp_no);
В СУБД Firebird, вплоть до этой версии, необходимо знать об особенности
реализации, которая проявляется в запросах на обновление записей, когда в
условии WHERE используется IN <select-expr>
и
<select-expr>
имеет вид SELECT FIRST
n
или SELECT ... ROWS. Например, запрос
UPDATE T
SET ...
WHERE ID IN (SELECT FIRST 1 ID FROM T)
приведёт к «бесконечному циклу обновления», постоянно выбирая строки и обновляя их снова и снова. Таким образом, создаётся впечатление, что сервер завис.
Эта особенность проявляется во всех DML операторах изменяющих данные, чаще всего когда условие отбора содержит подзапрос. Были случаи, когда порядок сортировки мешает ожиданиям, даже без использования подзапроса. Это происходит потому, что DML операторы используют неявные курсоры для выполнения операций над каждой строкой, не зная была ли она обновлена ранее, вместо создания стабильного «целевого множества» и выполнения изменений на каждом его элементе. Таким образом, следующий шаблон:
UPDATE T SET<fields>
=<values>
WHERE<conditions>
выполняется как
FOR SELECT<values>
FROM T WHERE<conditions>
INTO<tmp_vars>
AS CURSOR<cursor>
DO UPDATE T SET<fields>
=<tmp_vars>
WHERE CURRENT OF<cursor>
Такая реализация приводит к поведению, которое не согласуется с SQL стандартом, который требует чтобы стабильное множество было установлено перед любыми изменениями данных. В Firebird 3.0 эта ошибка исправлена.
Предложение PLAN позволяет вручную указать план для оптимизатора.
Примеры:
UPDATE company c SET c.company_name =
( SELECT k.contact_name
FROM contact k
WHERE k.id = c.contact_id
PLAN (K INDEX (CONTACT_ID)))
WHERE c.company_name IS NULL OR c.company_name = ''
PLAN (C NATURAL)
Предложение ORDER BY позволяет задать порядок обновления записей. Это может иметь значение в некоторых случаях.
Предложение ROWS имеет смысл только вместе с предложением ORDER BY. Однако его можно использовать отдельно.
При одном аргументе m
, ROWS ограничивает update первыми
m
строками. Особенности:
Если m
> количества обрабатываемых строк,
то обновляется весь набор строк;
Если m
= 0, ни одна строка не
обновляется;
Если m
< 0, выдаётся ошибка.
При двух аргументах m
и n
,
ROWS ограничивает update до строк от m
до
n
включительно. Оба аргумента – целочисленные, и
начинаются с 1. Особенности:
Если m
> количества обрабатываемых строк,
ни одна строка не обновляется;
Если n
больше количества строк, то
обновляются строки от m
до конца
набора;
Если m
< 1 или
n
< 1, выдаётся ошибка;
Если n
= m
- 1,
ни одна строка не обновляется;
Если n
< m
-
1, выдаётся ошибка.
Примеры:
Пример 5.4. Использование предложения ROWS в операторе UPDATE
-- дать надбавку 20ти сотрудникам с наименьшей зарплатой UPDATE employees SET salary = salary + 50 ORDER BY salary ASC ROWS 20;
Оператор UPDATE, обновляющий максимум одну строку, может включать RETURNING для возврата значений из обновляемой строки. В RETURNING могут включаться любые строки, необязательно только те, которые обновляются.
Возвращаемые значения содержат изменения, произведённые в триггерах BEFORE, но не
в триггерах AFTER. OLD.fieldname
и
NEW.fieldname
могут быть использованы в качестве имён
столбцов. Если OLD. Или NEW. не указано, возвращаются новые значения столбцов
(NEW.).
В DSQL оператор с RETURNING всегда возвращает только одну строку. Если записи не были обновлены оператором, то возвращаемые значения содержат NULL. Это поведение может быть изменено в последующих версиях Firebird.
Предложение INTO предназначено для передачи значений в локальные переменные. Оно доступно только в PSQL. Если записи не было обновлены, ничего не возвращается, и переменные, указанные в RETURING, сохранят свои прежние значения.
У столбцов, возвращаемых в контекстные переменные NEW в триггере, перед именем не должно использоваться двоеточие.
Пример 5.5. Использование предложения RETURNING в операторе UPDATE
UPDATE Scholars SET first_name = 'Hugh', last_name = 'Pickering' WHERE first_name = 'Henry' AND last_name = 'Higgins' RETURNING id, old.last_name, new.last_name;
Обновление столбцов BLOB всегда полностью меняет их содержимое. Даже идентификатор BLOB (ID), который является ссылкой на данные BLOB и хранится в столбце, меняется. BLOB могут быть изменены, если:
Клиентское приложение меняет BLOB посредством Firebird API. В этом случае все зависит от приложения, и не рассматривается в этом руководстве;
Длина строкового литерала не может превышать 32767 байт;
Если источником данных является столбец BLOB или выражение, возвращающее BLOB.
Назначение: Добавление новой или обновление существующей записи в таблице.
Доступно в: DSQL, PSQL.
Синтаксис:
UPDATE OR INSERT INTOtarget
[(<column_list>
)] VALUES (<value_list>
) [MATCHING (<column_list>
)] [RETURNING<returning_list>
[INTO<variables>
]]<column_list>
::=colname
[,colname
...]<value_list>
::=value
[,value
...]<returning_list>
::=ret_value
[,ret_value
...]<variables>
::= [:]varname
[, [:]varname
...]
Таблица 5.14. Параметры оператора UPDATE OR INSERT
Параметр | Описание |
---|---|
target |
Имя таблицы или представления, запись в которой будет обновлена или произойдет вставка новой записи. |
colname |
Столбец таблицы или представления. |
value |
Выражение, значение которого используется для вставки или обновления таблицы. |
ret_value |
Выражение, возвращаемое в предложении RETURNING. |
varname |
Имя PSQL переменной. |
Оператор UPDATE OR INSERT вставляет или обновляет одну или более существующих записей. Производимое действие зависит от значений столбцов в предложении MATCHING (или, если оно не указано, то от значений столбцов первичного ключа — PK). Если найдены записи, совпадающие с указанными значениями, то они обновляются. Если нет, то вставляется новая запись.
Совпадением считается полное совпадение значений столбцов MATCHING или PK. Совпадение проверяется с использованием IS NOT DISTINCT, поэтому NULL совпадает с NULL.
Если у таблицы нет первичного ключа, то указание MATCHING считается обязательным;
В списке MATCHING, так же как и в списке столбцов update/insert, каждый столбец может быть упомянут только один раз;
Предложение INTO доступно только в PSQL.
У столбцов, возвращаемых в контекстные переменные NEW в триггере, перед именем не должно использоваться двоеточие.
Предложение RETURNING может содержать любые столбцы, указанные в операторе, или
другие столбцы и выражения. Возвращаемые значения содержат все изменения,
произведённые в триггерах BEFORE, но не в триггерах AFTER.
OLD.fieldname
и
NEW.fieldname
могут быть использованы в качестве
возвращаемых значений. Для обычных имён столбцов возвращаются новые значения.
В DSQL, оператор с RETURNING всегда возвращает только одну строку. Если присутствует предложение RETURNING, и обнаружено более одной совпадающей строки, выдаётся сообщение об ошибке. Это поведение может быть изменено в последующих версиях Firebird.
Примеры: Использование оператора UPDATE OR INSERT
UPDATE OR INSERT INTO Cows (Name, Number, Location) VALUES ('Suzy Creamcheese', 3278823, 'Green Pastures') MATCHING (Number) RETURNING rec_id INTO :id;
Назначение: Удаление данных из таблицы.
Доступно в: DSQL, ESQL, PSQL.
Синтаксис:
DELETE FROMtarget
[[AS]alias
] [WHERE {search-conditions
| CURRENT OFcursorname
}] [PLANplan_items
] [ORDER BYsort_items
] [ROWSm
[TOn
]] [RETURNING<returning_list>
[INTO<variables>
]]<returning_list>
::=ret_value
[,ret_value
...]<variables>
::= [:]varname
[, [:]varname
...]
Таблица 5.15. Параметры оператора DELETE
Параметр | Описание |
---|---|
target |
Имя таблицы или представления, из которой удаляются записи. |
alias |
Псевдоним таблицы или представления. |
search-conditions |
Условие поиска, ограничивающее набор удаляемых строк. |
cursorname |
Имя курсора, по которому позиционируется удаляемая запись. |
plan_items |
Предложение плана. |
sort_items |
Предложение сортировки. |
m ,
n |
Целочисленные выражения для ограничения количества удаляемых строк. |
ret_value |
Выражение, возвращаемое в предложении RETURNING. |
varname |
Имя PSQL переменной. |
Оператор DELETE удаляет строки из таблицы или из одной и более таблиц представления.
Если для таблицы указан псевдоним, то он должен использоваться для всех столбцов таблицы.
Условие в предложении WHERE ограничивает набор удаляемых строк. Удаляются только те строки, которые удовлетворяют условию поиска, или только текущей строке именованного курсора.
Удаление с помощью WHERE CURRENT OF называется позиционированным удалением (positioned delete), потому что удаляется запись в текущей позиции. Удаление при помощи "WHERE условие" называется поисковым удалением (searched delete), поскольку Firebird ищет записи, соответствующие условию.
В чистом DSQL выражение WHERE CURRENT OF не имеет смысла, т.к. в DSQL нет оператора для создания курсора.
Примеры:
Пример 5.6. Использование предложения WHERE в операторе DELETE
DELETE FROM People WHERE first_name <> 'Boris' AND last_name <> 'Johnson';
DELETE FROM employee e WHERE NOT EXISTS( SELECT * FROM employee_project ep WHERE e.emp_no = ep.emp_no);
DELETE FROM Cities
WHERE CURRENT OF Cur_Cities; -- только в PSQL
Предложение PLAN позволяет вручную указать план для оптимизатора.
Примеры:
DELETE FROM Submissions
WHERE date_entered < '1-Jan-2002'
PLAN (Submissions INDEX ix_subm_date)
Предложение ORDER BY упорядочивает набор перед его удалением. Что может быть важно в некоторых случаях.
Предложение ROWS позволяет ограничить количество удаляемых строк. Имеет смысл только в комбинации с предложением ORDER BY, но допустимо и без него.
Синтаксис:
ROWS<m>
[TO<n>
]
В качестве m
и n
могут
выступать любые целочисленные выражения.
При одном аргументе m
, удаляются первые
m
строк. Порядок строк без ORDER BY не определён
(случаен).
Замечания:
Если m
больше общего числа строк в наборе,
то весь набор удаляется;
Если m
= 0, то удаление не
происходит;
Если m
< 0, то выдаётся сообщение об
ошибке.
Если указаны аргументы m
и
n
, удаление ограничено количеством строк от
m
до n
, включительно.
Нумерация строк начинается с 1.
Замечания по использованию двух аргументов:
Если m
> общего числа строк в наборе,
ни одна строка не удаляется;
Если m
> 0 и <= числа строк в наборе, а
n
вне этих значений, то удаляются строки
от m до конца набора;
Если m
< 1 или n < 1, выдаётся
сообщение об ошибке;
Если n
= m
– 1,
ни одна строка не удаляется;
Если n
< m
–
1, выдаётся сообщение об ошибке.
Примеры:
Удаление самой старой покупки
DELETE FROM Purchases ORDER BY ByDate ROWS 1
Удаление заказов для 10 клиентов с самыми большими номерами
DELETE FROM Sales ORDER BY custno DESC ROWS 1 TO 10Удаляет все записи из sales, поскольку не указано ROWS
DELETE FROM Sales ORDER BY custno DESCУдаляет одну запись "с конца", т.е. от Z…
DELETE FROM popgroups ORDER BY name DESC ROWS 1
Удаляет пять самых старых групп
DELETE FROM popgroups ORDER BY formed ROWS 5
Сортировка (ORDER BY) не указана, поэтому будут удалены 8 обнаруженных записей, начиная с пятой.
DELETE FROM popgroups ROWS 5 TO 12
Оператор DELETE, удаляющий не более одной строки, может содержать конструкцию RETURNING для возвращения значений удаляемой строки. В RETURNING могут быть указаны любые столбцы, не обязательно все, а также другие столбцы и выражения.
В DSQL, оператор с RETURNING всегда возвращает только одну строку. Если записи не были удалены, то возвращаемые столбцы содержат NULL. Это поведение может быть изменено в последующих версиях Firebird;
В PSQL, если строка не была удалена, ничего не возвращается, и целевые переменные сохраняют свои значения;
У столбцов, возвращаемых в контекстные переменные NEW в триггере, перед именем не должно использоваться двоеточие.
Предложение INTO доступно только в PSQL.
Примеры:
DELETE FROM Scholars WHERE first_name = 'Henry' AND last_name = 'Higgins' RETURNING last_name, fullname, id DELETE FROM Dumbbells ORDER BY iq DESC ROWS 1 RETURNING last_name, iq INTO :lname, :iq; DELETE FRMO TempSales ts WHERE ts.id = tempid RETURNING ts.qty INTO new.qty;
Из-за особенностей выполнения DML операторов изменяющих данные в СУБД Firebird, удаление данных на целевом множестве может привести к различным неожиданным результатам. Более подробная информация изложена в Проблема «Нестабильности курсора» секции UPDATE.
Назначение: Слияние записей источника в целевую таблицу (или обновляемое представление).
Доступно в: DSQL, PSQL.
Синтаксис:
MERGE INTOtarget
[AStarget_alias
] USING<source>
[ASsource_alias
] ON<join condition>
[ WHEN MATCHED THEN UPDATE SETcolname
=value
[,colname
=value
...]] [ WHEN NOT MATCHED THEN INSERT [(<column_list>
)] VALUES (<value_list>
)]<column_list>
::=colname
[,colname
...]<value_list>
::=value
[,value
...]
Таблица 5.16. Параметры оператора MERGE
Параметр | Описание |
---|---|
target |
Целевая таблица или обновляемое представление. |
source |
Источник данных. Может быть таблицей, представлением, хранимой процедурой или производной таблицей. |
target_alias |
Псевдоним целевой таблицы или представления. |
source_alias |
Псевдоним источника. |
join condition |
Условие соединения целевой таблицы и источника. |
colname |
Столбец целевой таблицы или представления. |
value |
Значение, присваиваемое столбцу целевой таблицы. Выражение, которое может содержать литералы, PSQL переменные, столбцы из источника. |
Оператор MERGE производит слияние записей источника в целевую таблицу (или обновляемое представление). Источником может быть таблица, представление, или "все то, к чему вы можете выполнить SELECT". Каждая запись источника используется для обновления одной или более записей цели, или вставки записи в целевую таблицу, или ни для того, ни для другого. Условие обычно содержит сравнение столбцов в таблицах источника и цели.
Допускается использование только одного WHEN MATCHED и одного WHEN NOT MATCHED.
WHEN NOT MATCHED оценивается с точки зрения источника, т.е. таблицы или набора данных указанного в предложения USING. Так сделано потому, что если запись источника не имеет совпадения с записью цели, то выполняется INSERT. Разумеется, если запись цели не соответствует запись в источнике, то никакие действия не производятся.
На данный момент переменная ROW_COUNT возвращает значение 1, даже если было модифицировано или вставлено более 1 записи. См. CORE-4400.
Если условие WHEN MATCHED присутствует, и несколько записей совпадают с записями в целевой таблице, UPDATE выполнится для всех совпадающих записей источника, и каждое последующее обновление перезапишет предыдущее. Это нестандартное поведение: стандарт SQL-2003 требует, чтобы в этой ситуации выдавалось исключение (ошибка).
Примеры:
MERGE INTO books b USING purchases p ON p.title = b.title AND p.booktype = 'bk' WHEN MATCHED THEN UPDATE SET b.descr = b.descr || '; ' || p.descr WHEN NOT MATCHED THEN INSERT (title, descr, bought) VALUES (p.title, p.descr, p.bought); -- с использованием производной таблицы MERGE INTO customers c USING (SELECT * FROM customers_delta WHERE id > 10) cd ON (c.id = cd.id) WHEN MATCHED THEN UPDATE SET name = cd.name WHEN NOT MATCHED THEN INSERT (id, name) VALUES (cd.id, cd.name); -- совместно с рекурсивным CTE MERGE INTO numbers USING ( WITH RECURSIVE r(n) AS ( SELECT 1 FROM rdb$database UNION ALL SELECT n+1 FROM r WHERE n < 200 ) SELECT n FROM r ) t ON numbers.num = t.n WHEN NOT MATCHED THEN INSERT(num) VALUES(t.n); -- с использованием предложения DELETE MERGE INTO SALARY_HISTORY USING ( SELECT EMP_NO FROM EMPLOYEE WHERE DEPT_NO = 120) EMP ON SALARY_HISTORY.EMP_NO = EMP.EMP_NO WHEN MATCHED THEN DELETE
Из-за особенностей выполнения DML операторов изменяющих данные в СУБД Firebird, слияние данных на целевом множестве может привести к различным неожиданным результатам. Более подробная информация изложена в Проблема «Нестабильности курсора» секции UPDATE.
Назначение: Выполнение хранимой процедуры.
Доступно в: DSQL, ESQL, PSQL.
Синтаксис:
EXECUTE PROCEDUREprocname
[<inparam>
[,<inparam>
...]] | ([<inparam>
[,<inparam>
...]]) [RETURNING_VALUES<outvar>
[,<outvar>
...]] | (<outvar>
[,<outvar>
...]])<outvar>
::= [:]varname
Таблица 5.17. Параметры оператора EXECUTE PROCEDURE
Параметр | Описание |
---|---|
procname |
Имя хранимой процедуры. |
inparam |
Выражение совместимое по типу с входным параметром хранимой процедуры. |
varname |
PSQL переменная, в которую возвращается значение выходного параметра процедуры. |
Оператор EXECUTE PROCEDURE выполняет хранимую процедуру, получая список из одного или нескольких входных параметров, если они определены, и возвращает однострочный набор значений, если он определён.
Оператор EXECUTE PROCEDURE является наиболее часто используемым стилем вызова хранимой процедуры, которая написана для модификации некоторых данных, код которой не содержит оператора SUSPEND. Такие хранимые процедуры могут возвратить набор данных, состоящий не более чем из одной строки. Этот набор может быть передан в переменные другой (вызывающей) процедуры с помощью предложения RETURNING_VALUES. Клиентские интерфейсы, как правило, имеют обертку API, которые могут извлекать выходные значения в однострочный буфер при вызове процедуры через EXECUTE PROCEDURE в DSQL.
При вызове с помощью EXECUTE PROCEDURE процедур другого типа (селективных процедур) будет возвращена только первая запись из результирующего набора, несмотря на то, что эта процедура скорее всего должна возвращать многострочный результат. "Селективные" хранимые процедуры должны вызываться с помощью оператора SELECT, в этом случае они ведут себя как виртуальные таблицы.
В PSQL И DSQL входными параметрами могут быть любые совместимые по типу выражения;
Несмотря на то, что скобки для отделения списка передаваемых параметров необязательны после имени хранимой процедуры, желательно их использовать;
В DSQL приложениях, использующих Firebird API или иную обёртку, вызов процедуры через EXECUTE PROCEDURE не требует указания предложения RETURNING_VALUES для получения выходных значений в однострочный буфер.
Примеры:
В PSQL (с опциональными двоеточиями):
EXECUTE PROCEDURE MakeFullName(:First_Name, :Middle_Name, :Last_Name) RETURNING_VALUES :FullName;
В утилите командной строки isql (с литералами в качестве параметров):
EXECUTE PROCEDURE MakeFullName 'J', 'Edgar', 'Hoover';
С выражениями в качестве параметров:
EXECUTE PROCEDURE MakeFullName ('Mr./Mrs. ' || First_Name, Middle_Name, upper(Last_Name)) RETURNING_VALUES FullName;
Назначение: Выполнение анонимного PSQL блока.
Доступно в: DSQL.
Синтаксис:
EXECUTE BLOCK [(<inparams>
)] [RETURNS (<outparams>
)] AS [<declarations>
] BEGIN [<PSQL statements>
] END<inparams>
::=<param_decl>
= ? [,<inparams>
]<outparams>
::=<param_decl>
[,<outparams>
]<param_decl>
::=paramname
<type>
[NOT NULL] [COLLATEcollation
]<type>
::=<datatype>
| [TYPE OF]domain
| TYPE OF COLUMNrel
.col
<datatype>
::= {SMALLINT | INT[EGER] | BIGINT} | {FLOAT | DOUBLE PRECISION} | {DATE | TIME | TIMESTAMP} | {DECIMAL | NUMERIC} [(precision
[,scale
])] | {CHAR | CHARACTER | CHARACTER VARYING | VARCHAR} [(size
)] [CHARACTER SETcharset
] | {NCHAR | NATIONAL CHARACTER | NATIONAL CHAR} [VARYING] [(size
)] | BLOB [SUB_TYPE {subtype_num
|subtype_name
}] [SEGMENT SIZEseglen
] [CHARACTER SETcharset
] | BLOB [(seglen
[,subtype_num
])]<declarations>
::=<declare_item>
[<declare_item>
...]<declare_item>
::=<declare_var>
; |<declare_cursor>
;
Таблица 5.18. Параметры оператора EXECUTE BLOCK
Параметр | Описание |
---|---|
param_decl |
Описание входного или выходного параметра. |
declarations |
Секция объявления локальных переменных, именованных курсоров, подпроцедур и подфункций. |
declare_var |
Объявление локальной переменной. |
declare_cursor |
Объявление именованного курсора. |
paramname |
Имя входного или выходного параметра процедуры. Может содержать до 31 символа. Имя параметра должно быть уникальным среди входных и выходных параметров процедуры, а также её локальных переменных. |
datatype |
Тип данных SQL. |
collation |
Порядок сортировки. |
domain |
Домен. |
rel |
Имя таблицы или представления. |
col |
Имя столбца таблицы или представления. |
precision |
Точность. От 1 до 18. |
scale |
Масштаб. От 0 до 18, должно быть меньше или равно
precision .
|
size |
Максимальный размер строки в символах. |
charset |
Набор символов. |
subtype_num |
Номер подтипа BLOB. |
subtype_name |
Мнемоника подтипа BLOB. |
seqlen |
Размер сегмента, не может превышать 65535. |
Выполняет блок PSQL кода, так как будто это хранимая процедура, возможно с входными и выходными параметрами и локальными переменными. Это позволяет пользователю выполнять "на лету" PSQL в контексте DSQL.
Примеры:
Этот пример вводит цифры от 0 до 127 и соответствующие им ASCII символов в таблицу ASCIITABLE:
EXECUTE BLOCK AS DECLARE i INT = 0; BEGIN WHILE (i < 128) DO BEGIN INSERT INTO AsciiTable VALUES (:i, ascii_char(:i)); i = i + 1; END END
Следующий пример вычисляет среднее геометрическое двух чисел и возвращает его пользователю:
EXECUTE BLOCK ( x DOUBLE PRECISION = ?, y DOUBLE PRECISION = ?) RETURNS (gmean DOUBLE PRECISION) AS BEGIN gmean = sqrt(x*y); SUSPEND; END
Поскольку этот блок имеет входные параметры, он должен быть предварительно подготовлен. После чего можно установить параметры и выполнить блок. Как это будет сделано, и вообще возможно ли это сделать, зависит от клиентского программного обеспечения. Смотрите примечания ниже.
Наш последний пример принимает два целочисленных значений, smallest и largest. Для всех чисел в диапазоне smallest..largest, блок выводит само число, его квадрат, куб и четвертую степень.
EXECUTE BLOCK (smallest INT = ?, largest INT = ?) RETURNS ( number INT, square BIGINT, cube BIGINT, fourth BIGINT) AS BEGIN number = smallest; WHILE (number <= largest) DO BEGIN square = number * number; cube = number * square; fourth = number * cube; SUSPEND; number = number + 1; END END
Опять же, как вы можете установить значения параметров, зависит от программного обеспечения клиента.
См. также: Операторы языка PSQL.
Выполнение блока без входных параметров должно быть возможным с любым клиентом Firebird, который позволяет пользователю вводить свои собственные DSQL операторы. Если есть входные параметры, все становится сложнее: эти параметры должны получить свои значения после подготовки оператора, но перед его выполнением. Это требует специальных возможностей, которыми располагает не каждое клиентское приложение (Например, isql такой возможности не предлагает).
Сервер принимает только вопросительные знаки ("?") в качестве
заполнителей для входных значений, а не ":а
",
":MyParam
" и т.д., или литеральные
значения. Клиентское программное обеспечение может поддерживать форму
":ххх
", в этом случае будет произведена
предварительная обработка запроса перед отправкой его на сервер.
Если блок имеет выходные параметры, вы должны использовать SUSPEND, иначе ничего не будет возвращено.
Выходные данные всегда возвращаются в виде набора данных, так же как и в случае с оператором SELECT. Вы не можете использовать RETURNING_VALUES или выполнить блок, вернув значения в некоторые переменные, используя INTO, даже если возвращается всего одна строка.
Для получения дополнительной информации о параметрах и объявлениях переменных,
[TYPE OF] domain
, TYPE OF COLUMN и т.д. обратитесь к
главе DECLARE.
Некоторые редакторы SQL-операторов — в частности утилита isql, которая идёт в комплекте с Firebird, и возможно некоторые сторонние редакторы — используют внутреннее соглашение, которое требует, чтобы все операторы были завершены с точкой с запятой.
Это создает конфликт с синтаксисом PSQL при кодировании в этих средах. Если вы не знакомы с этой проблемой и её решением, пожалуйста, изучите детали в главе PSQL в разделе, озаглавленном Изменение терминатора в isql.
Procedural SQL (PSQL) — процедурное расширение языка SQL. Это подмножество языка используется для написания хранимых процедур, триггеров и PSQL блоков.
Это расширение содержит все основные конструкции классических языков программирования. Кроме того, в него входят немного модифицированные DML операторы (SELECT, INSERT, UPDATE, DELETE и др.).
Процедурное расширение может содержать объявления локальных переменных и курсоров, операторы присваивания, условные операторы, операторы циклов, выброса пользовательского исключений, средства для обработки ошибок, отправки сообщений (событий) клиентским программам. Кроме того, в триггерах доступны специфичные контекстные переменные, такие как NEW и OLD.
В PSQL не допустимы операторы модификации метаданных (DDL операторы).
В DML (SELECT, INSERT, UPDATE, DELETE и др.) операторах допустимы только именованные параметры. Если DML операторы содержат именованные параметры, то они должны быть предварительно объявлены как локальные переменные в операторе DECLARE [VARIABLE] заголовка модуля или доступны во входных или выходных параметрах PSQL модуля.
При использовании именованных параметров в DML операторах необходим префикс двоеточия «:», однако в предложении INTO символ двоеточия не обязателен. Префикс двоеточия является необязательным в операторах специфичных для PSQL, таких как операторы ветвления или присваивания. Префикс двоеточия не требуется также при вызове хранимой процедуры с помощью оператора EXECUTE PROCEDURE из другого PSQL модуля.
Хранимые процедуры выполняются в контексте той транзакции, в которой они были запущены. Триггеры выполняются в контексте транзакции, в которой выполнялся DML оператор, вызвавший запуск триггера. Для триггеров на событие базы данных запускается отдельная транзакция.
В PSQL не допустимы операторы старта и завершения транзакций, но существует возможность запуска оператора или блока операторов в автономной транзакции.
В синтаксисе PSQL модулей можно выделить заголовок и тело. DDL операторы для их объявления являются сложными операторами, т.е. состоят из единственного оператора, который включает в себя блоки нескольких операторов. Такие операторы начинаются с глагола (CREATE, ALTER, DROP, RECREATE, CREATE OR ALTER) и завершаются последним оператором END тела модуля.
Заголовок содержит имя модуля и описание локальных переменных. Для хранимых процедур и PSQL блоков заголовок может содержать описание входных и выходных параметров. Заголовок триггеров не может содержать входных и выходных параметров.
В заголовке триггера обязательно указывается событие (или комбинация событий), при котором триггер будет вызван автоматически.
Тело PSQL модуля представляет собой блок операторов, содержащий описание выполняемых программой действий. Блок операторов заключается в операторные скобки BEGIN и END. В самих программах возможно присутствие произвольного количества блоков, как последовательных, так и вложенных друг в друга. Все операторы за исключением блоков BEGIN ... END отделяются друг от друга точкой с запятой (;). Никакой другой символ не является допустимым терминатором операторов PSQL.
Хранимая процедура является программой, хранящейся в области метаданных базы данных и выполняющейся на стороне сервера. К хранимой процедуре могут обращаться хранимые процедуры (в том числе и сама к себе), триггеры и клиентские программы. Если хранимая процедура вызывает саму себя, то такая хранимая процедура называется рекурсивной.
Хранимые процедуры имеют следующие преимущества:
Модульность: Приложения, работающие с одной и той же базой данных, могут использовать одну и ту же хранимую процедуру, тем самым уменьшив размер кода приложения и устранив дублирование кода.
Упрощение поддержки приложений: При изменении хранимой процедуры, изменения отражаются сразу во всех приложениях, без необходимости их перекомпиляции.
Увеличение производительности: Поскольку хранимые процедуры выполняются на стороне сервера, а не клиента, то это уменьшает сетевой трафик, что повышает производительность.
Существуют два вида хранимых процедур — выполняемые хранимые процедуры (executable stored procedures) и селективные процедуры (selectable stored procedures).
Выполняемые хранимые процедуры, осуществляют обработку данных, находящихся в базе данных. Эти процедуры могут получать входные параметры и возвращать одиночный набор выходных (RETURNS) параметров. Такие процедуры выполняются с помощью оператора EXECUTE PROCEDURE. См. пример создания выполняемой хранимой процедуры в конце раздела CREATE PROCEDURE главы «Операторы DDL».
Селективные хранимые процедуры обычно осуществляют выборку данных из базы данных и возвращают при этом произвольное количество строк.
Такие процедуры позволяют получать довольно сложные наборы данных, которые зачастую невозможно или весьма затруднительно получить с помощью обычных DSQL SELECT запросов. Обычно такие процедуры выполняют циклический процесс извлечения данных, возможно преобразуя их, прежде чем заполнить выходные переменные (параметры) новыми данными на каждой итерации цикла. Оператор SUSPEND, обычно расположенный в конце каждой итерации, заполняет буфер и ожидает пока вызывающая сторона не выберет (fetch) строку.
Селективные хранимые процедуры могут иметь входные параметры и выходное множество, заданное в предложении RETURNS заголовка процедуры.
Обращение к селективной хранимой процедуре осуществляется при помощи оператора SELECT (см. Выборка из селективной хранимой процедуры). См. пример создания хранимой процедуры выбора в конце раздела CREATE PROCEDURE главы «Операторы DDL».
Синтаксис создания выполняемых хранимых процедур и селективных процедур ничем не отличается.
Синтаксис (не полный):
CREATE PROCEDUREprocname
[(<inparam>
[,<inparam>
...])] RETURNS (<outparam>
[,<outparam>
...]) AS [<declarations>
] BEGIN [<PSQL_statements>
] END
Заголовок хранимой процедуры обязательно содержит имя процедуры, которое должно быть уникальным среди имён хранимых процедур, таблиц и представлений. В нем так же может быть описано некоторое количество входных и выходных параметров. Входные параметры перечисляются после имени процедуры внутри пары скобок. Выходные параметры, которые являются обязательными для селективных хранимых процедур, перечисляются внутри пары скобок в предложении RETURNS.
Тело хранимой процедуры может содержать объявление локальных переменных и курсоров. После секции объявления следует основной блок BEGIN ... END, в который заключается PSQL код процедуры. В этом блоке могут содержаться DML и PSQL операторы, а также вложенные BEGIN ... END блоки. Любой из BEGIN ... END блоков может быть пустым, в том числе и главный блок. Это позволяет разрабатывать процедуры пошагово, методом сверху вниз.
Более подробная информация приведена в главе Операторы DDL (CREATE PROCEDURE).
В существующих хранимых процедурах можно изменять набор входных и выходных параметров и тело процедуры.
Синтаксис (не полный):
ALTER PROCEDUREprocname
[(<inparam>
[,<inparam>
...])] RETURNS (<outparam>
[,<outparam>
...]) AS [<declarations>
] BEGIN [<PSQL_statements>
] END
Более подробная информация приведена в главе Операторы DDL ( ALTER PROCEDURE ).
Для удаления хранимых процедур используется оператор DROP PROCEDURE.
Синтаксис (полный):
DROP PROCEDURE procname
;
Более подробная информация приведена в главе Операторы DDL (DROP PROCEDURE).
В Firebird (до версии 3.0) нет PSQL функций. Однако вы можете использовать запрос или подзапрос к селективным хранимым процедурам для их замены.
Примеры:
SELECT PSQL_FUNC(T.col1) AS expr_col, col2 FROM T
Можно заменить на
SELECT (SELECT output_column FROM PSQL_PROC(T.col1)) AS expr_col, col2 FROM T
Или
SELECT output_column AS expr_col, col2, FROM T LEFT JOIN PSQL_PROC(T.col1) ON 1=1
Для выполнения из декларативного SQL (DSQL) некоторых императивных действий используются анонимные (безымянные) PSQL блоки. Заголовок анонимного PSQL блока опциально может содержать входные и выходные параметры. Тело анонимного PSQL блока может содержать объявление локальных переменных, курсоров и блок PSQL операторов.
Анонимный PSQL блок не определяется и сохраняется как объект метаданных, в отличии от хранимых процедур и триггеров. Он не может обращаться сам к себе.
Как и хранимые процедуры анонимные PSQL блоки могут использоваться для обработки данных или для осуществления выборки из базы данных.
Синтаксис (полный):
EXECUTE BLOCK [(<inparam>
= ? [,<inparam>
= ? ...])] [RETURNS (<outparam>
[,<outparam>
...])] AS [<declarations>
] BEGIN [<PSQL_statements>
] END
Таблица 6.2. Параметры оператора EXECUTE BLOCK
Параметр | Описание |
---|---|
inparam |
Описание входного параметра. |
outparam |
Описание выходного параметра. |
declarations |
Секция объявления локальных переменных и именованных курсоров. |
PSQL_statments |
Операторы языка PSQL. |
См. также: EXECUTE BLOCK.
Триггер является программой, которая хранится в области метаданных базы данных и выполняется на стороне сервера. Напрямую обращение к триггеру невозможно. Он вызывается автоматически при наступлении одного или нескольких событий, относящихся к одной конкретной таблице (к представлению), или при наступлении одного из событий базы данных.
Триггер, вызываемый при наступлении события таблицы, связан с одной таблицей или представлением, с одним или более событиями для этой таблицы или представления (INSERT, UPDATE, DELETE) и ровно с одной фазой такого события (BEFORE или AFTER).
Триггер выполняется в той транзакции, в контексте которой выполнялась программа, вызвавшая соответствующее событие. Исключением являются триггеры, реагирующие на события базы данных. Для некоторых из них запускается транзакция по умолчанию.
Для каждой комбинации фаза-событие может быть определено более одного триггера. Порядок, в котором они выполняются, может быть указан явно с помощью дополнительного аргумента POSITION в определении триггера. Максимальная позиция равна 32767. Триггеры с меньшей позицией вызываются первыми.
Если предложение POSITION опущено или несколько триггеров с одинаковыми фазой и событием имеют одну и ту же позицию, то такие триггеры будут выполняться в алфавитном порядке их имен.
DML триггеры вызываются при изменении состояния данных DML операциями: редактирование, добавление или удаление строк. Они могут быть определены и для таблиц и для представлений.
Существует шесть основных вариантов соотношения событие-фаза для таблицы (представления):
до добавления новой строки | (BEFORE INSERT) |
после добавления новой строки | (AFTER INSERT) |
до изменения строки | (BEFORE UPDATE) |
после изменения строки | (AFTER UPDATE) |
до удаления строки | (BEFORE DELETE) |
после удаления строки | (AFTER DELETE) |
Помимо базовых форм с единственной фазой и событием Firebird поддерживает также формы с одной фазой и множеством событий, например, BEFORE INSERT OR UPDATE OR DELETE или AFTER UPDATE OR DELETE или любая другая комбинация на ваш выбор.
Триггеры с несколькими фазами, такие как BEFORE OR AFTER ... не поддерживаются.
Контекстные переменные INSERTING, UPDATING и DELETING логического типа могут быть использованы в теле триггера для определения события, которое вызвало срабатывание триггера.
В DML триггерах Firebird обеспечивает доступ к множеству контекстных
переменных NEW.* и OLD.* Каждое множество является массивом всей строки: OLD.* —
значение строки до изменения данных и NEW.* — требуемое ("новое") значение
строки. Операторы могут ссылаться на них использую следующие формы
NEW.columname
и
OLD.columnname
.
columnname
может быть любым столбцом определённым
в таблице(представлении). а не только тем что был изменён.
Контекстные переменные NEW и OLD подчиняются следующим правилам:
Во всех триггерах контекстные переменные OLD доступны только для чтения;
В триггерах BEFORE UPDATE и BEFORE INSERT переменные NEW доступны для чтения и записи, за исключением COMPUTED BY столбцов;
В INSERT триггерах ссылка на переменные OLD не допускается и вызовет исключение;
В DELETE триггерах ссылка на переменные NEW не допускается и вызовет исключение;
Во всех AFTER триггерах переменные NEW доступны только для чтения.
Триггер, связанный с событиями базы данных, может вызываться при следующих событиях:
При соединении с базой данных | (ON CONNECT) | Перед выполнением триггера автоматически запускается транзакция по умолчанию |
При отсоединении от базы данных | (ON DISCONNECT) | Перед выполнением триггера автоматически запускается транзакция по умолчанию |
При старте транзакции | (ON TRANSACTION START) | Триггер выполняется в контексте текущей транзакции |
При подтверждении транзакции | (ON TRANSACTION COMMIT) | Триггер выполняется в контексте текущей транзакции |
При отмене транзакции | (ON TRANSACTION ROLLBACK) | Триггер выполняется в контексте текущей транзакции |
Синтаксис (не полный):
CREATE TRIGGERtrigname
{<relation_trigger_legacy>
|<relation_trigger_sql2003>
|<database_trigger>
} AS [<declarations>
] BEGIN [<PSQL_statements>
] END<relation_trigger_legacy>
::= FOR {tablename
|viewname
} [ACTIVE | INACTIVE] {BEFORE | AFTER}<mutation_list>
[POSITIONnumber
]<relation_trigger_sql2003>
::= [ACTIVE | INACTIVE] {BEFORE | AFTER}<mutation_list>
[POSITIONnumber
] ON {tablename
|viewname
}<database_trigger>
::= [ACTIVE | INACTIVE] ONdb_event
[POSITIONnumber
]<mutation_list>
::=<mutation>
[OR<mutation>
[OR<mutation>
]]<mutation>
::= { INSERT | UPDATE | DELETE }<db_event>
::= { CONNECT | DISCONNECT | TRANSACTION START | TRANSACTION COMMIT | TRANSACTION ROLLBACK }
Заголовок триггера обязательно содержит имя триггера, которое должно быть уникальным среди имён триггеров, и событие при котором срабатывает триггер. Если триггер создаётся для события таблицы, то необходимо также указать фазу события и имя таблицы.
Тело триггера может содержать объявление локальных переменных и курсоров. Оно также содержит блок операторов PSQL, который может быть пустым.
Более подробная информация приведена в главе Операторы DDL (CREATE TRIGGER).
В существующих триггерах можно изменить состояние активности, фазу события и событие (события) таблицы (представления), позицию триггера и его тело. Триггеры на событие (события) таблицы (представления) не могут быть изменены в триггеры на событие базы данных и наоборот. Если какой-либо элемент не указан, то он остаётся без изменений.
Синтаксис (не полный):
ALTER TRIGGERtrigname
[ACTIVE | INACTIVE] [ {{BEFORE | AFTER}<mutation_list>
} | ONdb_event
] [POSITIONnumber
] [ AS [<declarations>
] BEGIN [<PSQL_statements>
] END ]<mutation_list>
::=<mutation>
[OR<mutation>
[OR<mutation>
]]<mutation>
::= { INSERT | UPDATE | DELETE }<db_event>
::= { CONNECT | DISCONNECT | TRANSACTION START | TRANSACTION COMMIT | TRANSACTION ROLLBACK }
Более подробная информация приведена в главе Операторы DDL (ALTER TRIGGER).
Для удаления триггера используется оператор DROP TRIGGER.
Синтаксис:
DROP TRIGGER trigname
;
Более подробная информация приведена в главе Операторы DDL (DROP TRIGGER).
В этом разделе подробно рассматривается процедурные конструкции языка SQL и операторы доступные в теле хранимых процедур, триггеров и анонимных PSQL блоков.
Назначение: Присваивание переменной значения.
Доступно в: PSQL.
Синтаксис:
varname
=<value_expr>
Таблица 6.3. Параметры оператора присваивания
Параметр | Описание |
---|---|
varname |
Имя локальной переменной или параметра процедуры. |
value_expr |
Выражение, константа или переменная совместимая по типу
данных с |
PSQL использует символ равенства (=) в качестве своего оператора присваивания. Оператор присваивания устанавливает переменной слева от оператора значение SQL выражения справа. Выражением может быть любое правильное выражение SQL. Оно может содержать литералы, имена внутренних переменных, арифметические, логические и строковые операции, обращения к встроенным функциям и к функциям, определённым пользователем.
Примеры:
Пример 6.2. Использование оператора присваивания
CREATE PROCEDURE MYPROC ( a INTEGER, b INTEGER, name VARCHAR (30) ) RETURNS ( c INTEGER, str VARCHAR(100)) AS BEGIN -- присваиваем константу c = 0; str = ''; SUSPEND; -- присваиваем значения выражений c = a + b; str = name || CAST(b AS VARCHAR(10)); SUSPEND; -- присваиваем значение выражения -- построенного с использованием запроса c = (SELECT 1 FROM rdb$database); -- присваиваем значение из контекстной переменной str = CURRENT_USER; SUSPEND; END
См. также: DECLARE VARIABLE.
Назначение: Объявление локальной переменной или курсора.
Доступно в: PSQL.
Синтаксис:
DECLARE {<local_var>
|<cursor>
}
Оператор DECLARE предназначен для объявления локальной переменной или курсора. Каждый тип объявления будет рассмотрен отдельно.
Назначение: Объявление локальной переменной.
Доступно в: PSQL.
Синтаксис:
DECLARE [VARIABLE]varname
<type>
[NOT NULL] [COLLATEcollation
] [{= | DEFAULT}<value>
] }<value>
::= {literal
| NULL |context_var
}<type>
::=<datatype>
| [TYPE OF]domain
| TYPE OF COLUMNrel
.col
<datatype>
::= {SMALLINT | INT[EGER] | BIGINT} | {FLOAT | DOUBLE PRECISION} | {DATE | TIME | TIMESTAMP} | {DECIMAL | NUMERIC} [(precision
[,scale
])] | {CHAR | CHARACTER | CHARACTER VARYING | VARCHAR} [(size
)] [CHARACTER SETcharset
] | {NCHAR | NATIONAL CHARACTER | NATIONAL CHAR} [VARYING] [(size
)] | BLOB [SUB_TYPE {subtype_num
|subtype_name
}] [SEGMENT SIZEseglen
] [CHARACTER SETcharset
] | BLOB [(seglen
[,subtype_num
])]
Таблица 6.4. Параметры оператора DECLARE VARIABLE
Параметр | Описание |
---|---|
varname |
Имя локальной переменной. |
literal |
Литерал. |
context_var |
Любая контекстная переменная, тип которой совместим с типом локальной переменной. |
datatype |
Тип данных SQL. |
collation |
Порядок сортировки. |
domain |
Домен. |
rel |
Имя таблицы или представления. |
col |
Имя столбца таблицы или представления. |
precision |
Точность. От 1 до 18. |
scale |
Масштаб. От 0 до 18, должно быть меньше или равно
|
size |
Максимальный размер строки в символах. |
charset |
Набор символов. |
subtype_num |
Номер подтипа BLOB. |
subtype_name |
Мнемоника подтипа BLOB. |
seqlen |
Размер сегмента, не может превышать 65535. |
Оператор DECLARE [VARIBALE] объявляет локальную переменную. Ключевое слово VARIABLE можно опустить. В одном операторе разрешено объявлять только одну переменную. В процедурах и триггерах можно объявить произвольное число локальных переменных, используя при этом каждый раз, новый оператор DECLARE VARAIBLE.
Имя локальной переменной должно быть уникально среди имён локальных переменных, входных и выходных параметров процедуры внутри программного объекта.
В качестве типа данных локальной переменной может быть любой SQL тип, за исключением массивов.
В качестве типа переменной можно указать имя домена. В этом случае, переменная будет наследовать все характеристики домена. Если перед названием домена дополнительно используется предложение "TYPE OF", то используется только тип данных домена – не проверяется (не используется) его ограничение (если оно есть в домене) на NOT NULL, CHECK ограничения и/или значения по умолчанию. Если домен текстового типа, то всегда используется его набор символов и порядок сортировки.
Локальные переменные можно объявлять, используя тип данных столбцов существующих таблиц и представлений. Для этого используется предложение TYPE OF COLUMN, после которого указывается имя таблиц или представления и через точку имя столбца. При использовании TYPE OF COLUMN наследуется только тип данных, а в случае строковых типов ещё набор символов и порядок сортировки. Ограничения и значения по умолчанию столбца никогда не используются.
Для локальных переменных можно указать ограничение NOT NULL, тем самым запретив передавать в него значение NULL. Для переменной строкового типа существует возможность задать порядок сортировки с помощью предложения COLLATE.
Локальной переменной можно устанавливать инициализирующее (начальное) значение. Это значение устанавливается с помощью предложения DEFAULT или оператора "=". В качестве значения по умолчанию может быть использовано значение NULL, литерал и любая контекстная переменная совместимая по типу данных.
Обязательно используйте инициализацию начальным значением для любых переменных объявленных с ограничением NOT NULL, если они не получают значение по умолчанию иным способом.
Примеры:
Пример 6.3. Различные способы объявления локальных переменных
CREATE OR ALTER PROCEDURE SOME_PROC AS -- Объявление переменной типа INT DECLARE I INT; -- Объявление переменной типа INT не допускающей значение NULL DECLARE VARIABLE J INT NOT NULL; -- Объявление переменной типа INT со значением по умолчанию 0 DECLARE VARIABLE K INT DEFAULT 0; -- Объявление переменной типа INT со значением по умолчанию 1 DECLARE VARIABLE L INT = 1; -- Объявление переменной на основе домена COUNTRYNAME DECLARE FARM_COUNTRY COUNTRYNAME; -- Объявление переменной с типом равным типу домена COUNTRYNAME DECLARE FROM_COUNTRY TYPE OF COUNTRYNAME; -- Объявление переменной с типом столбца CAPITAL таблицы COUNTRY DECLARE CAPITAL TYPE OF COLUMN COUNTRY.CAPITAL; BEGIN /* Операторы PSQL */ END
См. также: Типы и подтипы данных, Пользовательские типы данных — домены, CREATE DOMAIN
Назначение: Объявление курсора.
Доступно в: PSQL.
Синтаксис:
DECLARE [VARIABLE]cursor_name
CURSOR FOR (<select_statement>
);
Таблица 6.5. Параметры оператора DECLARE CURSOR
Параметр | Описание |
---|---|
cursor_name |
Имя курсора. |
select_statement |
Оператор SELECT. |
Оператор DECLARE ... CURSOR FOR объявляет именованный курсор, связывая его с набором данных, полученным в операторе SELECT, указанном в предложении CURSOR FOR. В дальнейшем курсор может быть открыт, использоваться для обхода результирующего набора данных, и снова быть закрытым. Также поддерживаются позиционированные обновления и удаления при использовании WHERE CURRENT OF в операторах UPDATE и DELETE.
Предложение "FOR UPDATE" разрешено использовать в операторе SELECT, но оно не требуется для успешного выполнения позиционированного обновления или удаления;
Удостоверьтесь, что объявленные имена курсоров не совпадают, ни с какими именами, определёнными позже в предложениях AS CURSOR;
Если курсор требуется только для прохода по результирующему набору данных, то практически всегда проще (и менее подвержено ошибкам) использовать оператор FOR SELECT с предложением AS CURSOR. Объявленные курсоры должны быть явно открыты, использованы для выборки данных и закрыты. Кроме того, вы должны проверить контекстную переменную ROW_COUNT после каждой выборки и выйти из цикла, если её значение ноль. Предложение FOR SELECT делает эту проверку автоматически. Однако объявленные курсоры дают большие возможности для контроля над последовательными событиями и позволяют управлять несколькими курсорами параллельно;
Оператор SELECT может содержать параметры, например: "SELECT NAME || :SFX FROM NAMES WHERE NUMBER = :NUM". Каждый параметр должен быть заранее объявлен как переменная PSQL (это касается также входных и выходных параметров). При открытии курсора параметру присваивается текущее значение переменной.
Если значение переменной PSQL, используемой в операторе SELECT, изменяется во время выполнения цикла, то её новое значение может (но не всегда) использоваться при выборке следующих строк. Лучше избегать таких ситуаций. Если вам действительно требуется такое поведение, то необходимо тщательно протестировать код и убедиться, что вы точно знаете, как изменения переменной влияют на результаты выборки. Особо отмечу, что поведение может зависеть от плана запроса, в частности, от используемых индексов. В настоящее время нет строгих правил для таких ситуаций, но в новых версиях Firebird это может измениться.
Пример 6.4. Объявление именованного курсора
CREATE OR ALTER TRIGGER TBU_STOCK BEFORE UPDATE ON STOCK AS -- Объявление именованного курсора DECLARE C_COUNTRY CURSOR FOR ( SELECT COUNTRY, CAPITAL FROM COUNTRY ); BEGIN /* Операторы PSQL */ END
Пример 6.5. Использования именованных скриптов в PSQL блоке для получения списка скриптов для создания представлений
EXECUTE BLOCK RETURNS ( SCRIPT BLOB SUB_TYPE TEXT) AS DECLARE VARIABLE FIELDS VARCHAR(8191); DECLARE VARIABLE FIELD_NAME TYPE OF RDB$FIELD_NAME; DECLARE VARIABLE RELATION RDB$RELATION_NAME; DECLARE VARIABLE SRC TYPE OF COLUMN RDB$RELATIONS.RDB$VIEW_SOURCE; -- Объявление именованного курсора DECLARE VARIABLE CUR_R CURSOR FOR ( SELECT RDB$RELATION_NAME, RDB$VIEW_SOURCE FROM RDB$RELATIONS WHERE RDB$VIEW_SOURCE IS NOT NULL); -- Объявление именованного курсора, в котором -- используется локальная переменная DECLARE CUR_F CURSOR FOR ( SELECT RDB$FIELD_NAME FROM RDB$RELATION_FIELDS WHERE -- Важно переменная должна быть объявлена ранее RDB$RELATION_NAME = :RELATION); BEGIN OPEN CUR_R; WHILE (1 = 1) DO BEGIN FETCH CUR_R INTO :RELATION, :SRC; IF (ROW_COUNT = 0) THEN LEAVE; FIELDS = NULL; -- Курсор CUR_F будет использовать значение -- переменной RELATION инициализированной выше OPEN CUR_F; WHILE (1 = 1) DO BEGIN FETCH CUR_F INTO :FIELD_NAME; IF (ROW_COUNT = 0) THEN LEAVE; IF (FIELDS IS NULL) THEN FIELDS = TRIM(FIELD_NAME); ELSE FIELDS = FIELDS || ', ' || TRIM(FIELD_NAME); END CLOSE CUR_F; SCRIPT = 'CREATE VIEW ' || RELATION; IF (FIELDS IS NOT NULL) THEN SCRIPT = SCRIPT || ' (' || FIELDS || ')'; SCRIPT = SCRIPT || ' AS ' || ASCII_CHAR(13); SCRIPT = SCRIPT || SRC; SUSPEND; END CLOSE CUR_R; END
См. также: OPEN, FETCH, CLOSE, FOR SELECT.
Назначение: Обозначение блока операторов.
Доступно в: PSQL.
Синтаксис:
<block>
::= BEGIN<compound_statement>
[<compound_statement>
...] END<compound_statement>
::= {<block>
|<statement>
;}
Операторные скобки BEGIN ... END определяют блок операторов, которые выполняются как один оператор. Каждый блок начинается оператором BEGIN и завершается оператором END. Блоки могут быть вложенными, глубина вложения не ограничена. Блоки могут быть пустыми, что позволяет использовать его как заглушку, позволяющую избежать написания фиктивных операторов.
После операторов BEGIN и END точка с запятой не ставится. Однако утилита командной строки isql требует, чтобы после последнего оператора END в определении PSQL модуля следовал символ терминатора, установленного командой SET TERM. Терминатор не является частью синтаксиса PSQL.
Последний оператор END в триггере завершает работу триггера. Последний оператор END в хранимой процедуре работает в зависимости от типа процедуры:
В селективной процедуре последний оператор END возвращает управление приложению и устанавливает значение SQLCODE равным 100, что означает, что больше нет строк для извлечения;
В выполняемой процедуре последний оператор END возвращает управление и текущие значения выходных параметров, если таковые имеются, вызывающему приложению.
Примеры:
Пример 6.6. Использование BEGIN ... END
SET TERM ^; CREATE OR ALTER PROCEDURE DEPT_BUDGET ( DNO CHAR(3)) RETURNS ( TOT DECIMAL(12,2)) AS DECLARE VARIABLE SUMB DECIMAL(12,2); DECLARE VARIABLE RDNO CHAR(3); DECLARE VARIABLE CNT INTEGER; BEGIN TOT = 0; SELECT BUDGET FROM DEPARTMENT WHERE DEPT_NO = :DNO INTO :TOT; SELECT COUNT(BUDGET) FROM DEPARTMENT WHERE HEAD_DEPT = :DNO INTO :CNT; IF (CNT = 0) THEN SUSPEND; FOR SELECT DEPT_NO FROM DEPARTMENT WHERE HEAD_DEPT = :DNO INTO :RDNO DO BEGIN EXECUTE PROCEDURE DEPT_BUDGET(:RDNO) RETURNING_VALUES :SUMB; TOT = TOT + SUMB; END SUSPEND; END^ SET TERM ;^
Назначение: Условный переход.
Доступно в: PSQL.
Синтаксис:
IF (<condition>
) THEN<compound_statement>
[ELSE<compound_statement>
]
Таблица 6.6. Параметры оператора IF ... THEN ... ELSE
Параметр | Описание |
---|---|
condition |
Логическое условие возвращающее TRUE, FALSE или UNKNOWN. |
compound_statement |
Оператор или блок операторов. |
Оператор условного перехода IF используется для выполнения ветвления процесса обработки данных в PSQL. Если условие возвращает значение TRUE, то выполняется оператор или блок операторов после ключевого слова THEN. Иначе (если условие возвращает FALSE или UNKNOWN) выполняется оператор или блок операторов после ключевого слова ELSE, если оно присутствует. Условие всегда заключается в круглые скобки.
Примеры:
Пример 6.7. Использование оператора IF
...
IF (FIRST IS NOT NULL) THEN
LINE2 = FIRST || ' ' || LAST;
ELSE
LINE2 = LAST;
...
См. также: WHILE ... DO, CASE.
Назначение: Циклическое выполнение операторов.
Доступно в: PSQL.
Синтаксис:
WHILE (<condition>
) DO<compound_statement>
Таблица 6.7. Параметры оператора WHILE ... DO
Параметр | Описание |
---|---|
condition |
Логическое условие возвращающее TRUE, FALSE или UNKNOWN. |
compound_statement |
Оператор или блок операторов. |
Оператор WHILE используется для организации циклов в PSQL. Оператор или блок операторов будут выполняться до тех пор, пока условие истинно (возвращает TRUE). Циклы могут быть вложенными, глубина вложения не ограничена.
Примеры:
Пример 6.8. Использование оператора WHILE ... DO
Процедура расчёта суммы от 1 до I для демонстрации использования цикла:
CREATE PROCEDURE SUM_INT (I INTEGER) RETURNS (S INTEGER) AS BEGIN s = 0; WHILE (i > 0) DO BEGIN s = s + i; i = i - 1; END END
При выполнении в isql
EXECUTE PROCEDURE SUM_INT(4);
результат будет следующий
S ========== 10
См. также: FOR SELECT, FOR EXECUTE STATEMENT, LEAVE.
Назначение: Выход из цикла.
Синтаксис:
{FOR<select_stmt>
| WHILE (<condition>
)} DO BEGIN ... BREAK; ... END
Оператор BREAK моментально прекращает работу внутреннего цикла операторов WHILE или FOR.
Этот оператор считается устаревшим. Начиная с Firebird 1.5 рекомендуется использовать SQL-99 совместимый оператор LEAVE.
Назначение: Выход из цикла.
Доступно в: PSQL.
Синтаксис:
[label
:] {FOR<select_stmt>
| WHILE (<condition>
)} DO BEGIN ... LEAVE [label
]; ... END
Таблица 6.8. Параметры оператора LEAVE
Параметр | Описание |
---|---|
label |
Метка. |
select_stmt |
Оператор SELECT. |
condition |
Логическое условие возвращающее TRUE, FALSE или UNKNOWN. |
Оператор LEAVE моментально прекращает работу внутреннего цикла операторов WHILE или FOR. С использованием опционального параметра метки LEAVE также может выйти и из внешних циклов, при этом выполнение кода продолжается с первого оператора, следующего после прекращения блока внешнего цикла.
Примеры:
Пример 6.9. Использование оператора LEAVE
/* * Выход из цикла при возникновении ошибки вставки в таблицу NUMBERS. * Код продолжается со строки C = 0. */ ... WHILE (B < 10) DO BEGIN INSERT INTO NUMBERS(B) VALUES (:B); B = B + 1; WHEN ANY DO BEGIN EXECUTE PROCEDURE LOG_ERROR ( CURRENT_TIMESTAMP, 'ERROR IN B LOOP'); LEAVE; END END C = 0; ...
Пример 6.10. Использование оператора LEAVE с меткой
/* * "LEAVE LOOPA" завершает внешний цикл, а "LEAVE LOOPB" - внутренний. * Обратите внимание: простого оператора "LEAVE" также было бы достаточно, * чтобы завершить внутренний цикл. */ ... STMT1 = 'SELECT NAME FROM FARMS'; LOOPA: FOR EXECUTE STATEMENT :STMT1 INTO :FARM DO BEGIN STMT2 = 'SELECT NAME ' || 'FROM ANIMALS WHERE FARM = '''; LOOPB: FOR EXECUTE STATEMENT :STMT2 || :FARM || '''' INTO :ANIMAL DO BEGIN IF (ANIMAL = 'FLUFFY') THEN LEAVE LOOPB; ELSE IF (ANIMAL = FARM) THEN LEAVE LOOPA; ELSE SUSPEND; END END ...
См. также: EXIT.
Назначение: Завершение работы процедуры или триггера.
Доступно в: PSQL.
Синтаксис:
EXIT
Оператор EXIT позволяет из любой точки триггера или хранимой процедуры перейти на последний оператор END, то есть завершить выполнение программы.
Примеры:
Пример 6.11. Использование оператора EXIT в селективной хранимой процедуре.
CREATE PROCEDURE GEN_100 RETURNS ( I INTEGER ) AS BEGIN I = 1; WHILE (1=1) DO BEGIN SUSPEND; IF (I=100) THEN EXIT; I = I + 1; END END
Передача значений параметров в буфер и приостановка выполнения процедуры (PSQL блока) до тех пор, пока вызывающая сторона не получит результат.
Доступно в: PSQL.
Синтаксис:
SUSPEND
Оператор SUSPEND передаёт значения выходных параметров в буфер и приостанавливает выполнение хранимой процедуры (PSQL блока). Выполнение остаётся приостановленным до тех пор, пока вызывающая сторона не получит содержимое буфера. Выполнение возобновляется с оператора, следующего непосредственно после оператора SUSPEND. Чаще всего это будет новой итерацией циклического процесса.
Приложения, использующие API интерфейсы, обычно делают выборку из хранимых процедур прозрачно.
Если оператор SUSPEND выдаётся в исполняемой (executable) хранимой процедуре, то это равносильно выполнению оператора EXIT, в результате чего завершается работа процедуры.
Оператор SUSPEND "разрывает" атомарность блока, внутри которого он находится. В случае возникновения ошибки в селективной процедуре, операторы, выполненные после последнего оператора SUSPEND, будут откачены. Операторы, выполненные до последнего оператора SUSPEND, не будут откачены, если не будет выполнен откат транзакции.
Примеры:
Пример 6.12. Использование оператора SUSPEND в селективной хранимой процедуре.
CREATE PROCEDURE GEN_100 RETURNS ( I INTEGER ) AS BEGIN I = 1; WHILE (1=1) DO BEGIN SUSPEND; IF (I=100) THEN EXIT; I = I + 1; END END
См. также: EXIT.
Назначение: Выполнение динамически созданных SQL операторов.
Доступно в: PSQL.
Синтаксис:
<execute_statement>
::= EXECUTE STATEMENT<argument>
[<option>
...] [INTO<variables>
]<argument>
::=paramless_stmt
| (paramless_stmt
) | (<stmt_with_params>
) (<param_values>
)<param_values>
::=<named_values>
|<positional_values>
<named_values>
::=paramname
:=value_expr
[,paramname
:=value_expr
...]<positional_values>
::=value_expr
[,value_expr
...]<option>
::= WITH {AUTONOMOUS | COMMON} TRANSACTION | WITH CALLER PRIVILEGES | AS USERuser
| PASSWORDpassword
| ROLErole
| ON EXTERNAL [DATA SOURCE]<connect_string>
<connect_string>
::= [<hostspec>
] {filepath
|db_alias
}<hostspec>
::=<tcpip_hostspec>
|<netbeui_hostspec>
<tcpip_hostspec>
::=hostname
:<netbeui_hostspec>
::= \\hostname
\<variables>
::= [:]varname
[, [:]varname
...]
Таблица 6.9. Параметры оператора EXECUTE STATEMENT
Параметр | Описание |
---|---|
paramless_stmt |
Строки или переменная, содержащая не параметризованный SQL запрос. |
stmt_with_params |
Строки или переменная, содержащая параметризованный SQL запрос. |
paramname |
Имя параметра SQL запроса. |
value_expr |
Выражение. |
user |
Имя пользователя. Может быть строкой или переменной. |
password |
Пароль. Может быть строкой или переменной. |
role |
Роль. Может быть строкой или переменной. |
connection_string |
Строка соединения. Может быть строкой или переменной. |
filepath |
Путь к первичному файлу базы данных. |
db_alias |
Псевдоним базы данных. |
hostname |
Имя компьютера или IP адрес. |
varname |
Переменная. |
Оператор EXECUTE STATEMENT принимает строковый параметр и выполняет его, как будто это оператор DSQL. Если оператор возвращает данные, то с помощью предложения INTO их можно передать в локальные переменные.
В DSQL операторе можно использовать параметры. Параметры могут быть именованными и позиционными (безымянные). Значение должно быть присвоено каждому параметру.
Одновременное использование именованных и позиционных параметров в одном запросе запрещёно;
Если у оператора есть параметры, они должны быть помещёны в круглые скобки при вызове EXECUTE STATEMENT, независимо от вида их представления: непосредственно в виде строки, как имя переменной или как выражение;
Именованным параметрам должно предшествовать двоеточие (:) в самом операторе, но не при присвоении значения параметру;
Передача значений безымянным параметрам должна происходить в том же порядке, в каком они встречаются в тексте запроса;
Присвоение значений параметров должно осуществляться при помощи специального оператора ":=", аналогичного оператору присваивания языка Pascal;
Каждый именованный параметр может использоваться в операторе несколько раз, но только один раз при присвоении значения;
Для позиционных параметров число подставляемых значений должно точно равняться числу параметров (вопросительных знаков) в операторе.
Примеры:
Пример 6.13. С именованными параметрами:
... DECLARE license_num VARCHAR(15); DECLARE connect_string VARCHAR (100); DECLARE stmt VARCHAR (100) = 'SELECT license FROM cars WHERE driver = :driver AND location = :loc'; BEGIN ... SELECT connstr FROM databases WHERE cust_id = :id INTO connect_string; ... FOR SELECT id FROM drivers INTO current_driver DO BEGIN FOR SELECT location FROM driver_locations WHERE driver_id = :current_driver INTO current_location DO BEGIN ... EXECUTE STATEMENT (stmt) (driver := current_driver, loc := current_location) ON EXTERNAL connect_string INTO license_num; ...
Пример 6.14. С позиционными параметрами:
DECLARE license_num VARCHAR (15); DECLARE connect_string VARCHAR (100); DECLARE stmt VARCHAR (100) = 'SELECT license FROM cars WHERE driver = ? AND location = ?'; BEGIN ... SELECT connstr FROM databases WHERE cust_id = :id INTO connect_string; ... FOR SELECT id FROM drivers INTO current_driver DO BEGIN FOR SELECT location FROM driver_locations WHERE driver_id = :current_driver INTO current_location DO BEGIN ... EXECUTE STATEMENT (stmt) (current_driver, current_location) ON EXTERNAL connect_string INTO license_num; ...
По умолчанию оператор выполняется в контексте текущей транзакции. При использовании предложения WITH AUTONOMOUS TRANSACTION запускается новая транзакция с такими же параметрами, как и текущая. Она будет подтверждена, если оператор выполнился без ошибок и отменена (откачена) в противном случае. С предложением WITH COMMON TRANSACTION по возможности используется текущая транзакция.
Если оператор должен работать в отдельном соединении, то используется уже запущенная в этом соединении транзакция (если таковая транзакция имеется). В противном случае стартует новая транзакция с параметрами текущей транзакции. Любые новые транзакции, запущенные в режиме "COMMON", подтверждаются или откатываются вместе с текущей транзакцией.
По умолчанию операторы SQL выполняются с правами текущего пользователя. Спецификация WITH CALLER PRIVILEGES добавляет к ним привилегии для вызова хранимой процедуры или триггера, так же, как если бы оператор выполнялся непосредственно подпрограммой. WITH CALLER PRIVILEGES не имеет никакого эффекта, если также присутствует предложение ON EXTERNAL.
С предложением ON EXTERNAL DATA SOURCE оператор выполняется в отдельном соединении с той же или другой базой данных, возможно даже на другом сервере. Если строка подключения имеет значение NULL или '' (пустая строка), предложение ON EXTERNAL считается отсутствующим и оператор выполняется для текущей базы данных.
При выполнении оператора в отдельном соединении используется пул соединений и пул транзакций.
Внешние соединения используют по умолчанию предложение WITH COMMON TRANSACTION и остаются открытыми до закрытия текущей транзакции. Они могут быть снова использованы при последующих вызовах оператора EXECUTE STATEMENT, но только если строка подключения точно такая же;
Внешние соединения, созданные с использованием предложения WITH AUTONOMOUS TRANSACTION, закрываются после выполнения оператора;
Операторы WITH AUTONOMOUS TRANSACTION могут использовать соединения, которые ранее были открыты операторами WITH COMMON TRANSACTION. В этом случае использованное соединение остаётся открытым и после выполнения оператора, т.к. у этого соединения есть, по крайней мере, одна не закрытая транзакция.
При использовании предложения WITH COMMON TRANSACTION транзакции будут снова использованы как можно дольше. Они будут подтверждаться или откатываться вместе с текущей транзакцией;
При использовании предложения WITH AUTONOMOUS TRANSACTION всегда запускается новая транзакция. Она будет подтверждена или отменена сразу же после выполнения оператора;
При использовании предложения ON EXTERNAL дополнительное соединение всегда делается через так называемого внешнего провайдера, даже если это соединение к текущей базе данных. Одним из последствий этого является то, что вы не можете обработать исключение привычными способами. Каждое исключение, вызванное оператором, возвращает eds_connection или eds_statement ошибки. Для обработки исключений в коде PSQL вы должны использовать WHEN GDSCODE eds_connection, WHEN GDSCODE eds_statement или WHEN ANY.
Если предложение ON EXTERNAL не используется, то исключения перехватываются в обычном порядке, даже если это дополнительное соединение с текущей базой данных.
Необязательные предложения AS USER, PASSWORD и ROLE позволяют указывать от имени какого пользователя, и с какой ролью будет выполняться SQL оператор. То, как авторизуется пользователь и открыто ли отдельное соединение, зависит от присутствия и значений параметров ON EXTERNAL [DATA SOURCE], AS USER, PASSWORD и ROLE.
При использовании предложения ON EXTERNAL открывается новое соединение и:
Если присутствует, по крайней мере, один из параметров AS USER, PASSWORD и ROLE, то будет предпринята попытка нативной аутентификации с указанными значениями параметров (в зависимости от строки соединения — локально или удалённо). Для недостающих параметров не используются никаких значений по умолчанию;
Если все три параметра отсутствуют, и строка подключения не содержит имени сервера (или IP адреса), то новое соединение устанавливается к локальному серверу с пользователем и ролью текущего соединения. Термин 'локальный' означает 'компьютер, где установлен сервер Firebird'. Это совсем не обязательно компьютер клиента;
Если все три параметра отсутствуют, но строка подключения содержит имя сервера (или IP адреса), то будет предпринята попытка доверенной (trusted) авторизации к удалённому серверу. Если авторизация прошла, то удалённая операционная система назначит пользователю имя — обычно это учётная запись, под которой работает сервер Firebird.
Если предложение ON EXTERNAL отсутствует:
Если присутствует, по крайней мере, один из параметров AS USER, PASSWORD и ROLE, то будет открыто соединение к текущей базе данных с указанными значениями параметров. Для недостающих параметров не используются никаких значений по умолчанию;
Если все три параметра отсутствуют, то оператор выполняется в текущем соединении.
Если значение параметра NULL или '', то весь параметр считается отсутствующим. Кроме того, если параметр считается отсутствующим, то AS USER принимает значение CURRENT_USER, а ROLE — CURRENT_ROLE. Сравнение при авторизации сделано чувствительным к регистру: в большинстве случаев это означает, что имена пользователя и роли должны быть написаны в верхнем регистре.
Не существует способа проверить синтаксис выполняемого SQL оператора;
Нет никаких проверок зависимостей для обнаружения удалённых столбцов в таблице или самой таблицы;
Выполнение оператора с помощью оператора EXECUTE STATEMENT значительно медленнее, чем при непосредственном выполнении;
Возвращаемые значения строго проверяются на тип данных во избежание непредсказуемых исключений преобразования типа. Например, строка '1234' преобразуется в целое число 1234, а строка 'abc' вызовет ошибку преобразования.
В целом эта функция должна использоваться очень осторожно, а вышеупомянутые факторы всегда должны приниматься во внимание. Если такого же результата можно достичь с использованием PSQL и/или DSQL, то это всегда предпочтительнее.
См. также: FOR EXECUTE STATEMENT.
Назначение: Цикл по строкам результата выполнения оператора SELECT.
Доступно в: PSQL.
Синтаксис:
FOR<select_stmt>
INTO<variables>
[AS CURSORcursorname
] DO<compound_statement>
<variables>
::= [:]varname
[, [:]varname
...]
Таблица 6.10. Параметры оператора FOR SELECT
Параметр | Описание |
---|---|
select_stmt |
Оператор SELECT. |
cursorname |
Имя курсора. Должно быть уникальным среди имён переменных и курсоров PSQL модуля. |
varname |
Имя локальной переменной или входного/выходного параметра. |
compound_statement |
Оператор или блок операторов. |
Оператор FOR SELECT выбирает очередную строку из таблицы (представления, селективной хранимой процедуры), после чего выполняется оператор или блок операторов. В каждой итерации цикла значения полей текущей строки копируются в локальные переменные. Добавление предложения AS CURSOR делает возможным позиционное удаление и обновление данных. Операторы FOR SELECT могут быть вложенными.
Оператор FOR SELECT может содержать именованные параметры, которые должны быть предварительно объявлены в операторе DECLARE VARIABLE, или во входных (выходных) параметрах процедуры (PSQL блока).
Оператор FOR SELECT должен содержать предложение INTO, которое располагается в конце этого оператора, или предложение AS CURSOR. На каждой итерации цикла в список переменных указанных в предложении INTO копируются значения полей текущей строки запроса. Цикл повторяется, пока не будут прочитаны все строки. После этого происходит выход из цикла. Цикл также может быть завершён до прочтения всех строк при использовании оператора LEAVE.
Необязательное предложение AS CURSOR создаёт именованный курсор, на который можно ссылаться (с использованием предложения WHERE CURRENT OF) внутри оператора или блока операторов следующего после предложения DO, для того чтобы удалить или модифицировать текущую строку.
Над курсором, объявленным с помощью предложения AS CURSOR нельзя выполнять операторы OPEN, FETCH и CLOSE;
Убедитесь, что имя курсора, определённое здесь, не совпадает ни с какими именами, созданными ранее оператором DECLARE VARIABLE;
Предложение FOR UPDATE, разрешённое для использования в операторе SELECT, не является обязательным для успешного выполнения позиционного обновления или удаления.
Примеры:
Пример 6.15. Использование оператора FOR SELECT
CREATE PROCEDURE SHOWNUMS RETURNS ( AA INTEGER, BB INTEGER, SM INTEGER, DF INTEGER) AS BEGIN FOR SELECT DISTINCT A, B FROM NUMBERS ORDER BY A, B INTO AA, BB DO BEGIN SM = AA + BB; DF = AA - BB; SUSPEND; END END
Пример 6.16. Вложенный FOR SELECT
CREATE PROCEDURE RELFIELDS RETURNS ( RELATION CHAR(32), POS INTEGER, FIELD CHAR(32)) AS BEGIN FOR SELECT RDB$RELATION_NAME FROM RDB$RELATIONS ORDER BY 1 INTO :RELATION DO BEGIN FOR SELECT RDB$FIELD_POSITION + 1, RDB$FIELD_NAME FROM RDB$RELATION_FIELDS WHERE RDB$RELATION_NAME = :RELATION ORDER BY RDB$FIELD_POSITION INTO :POS, :FIELD DO BEGIN IF (POS = 2) THEN RELATION = ' "'; -- Для исключения повтора имён таблиц и представлений SUSPEND; END END END
Пример 6.17. Использование предложения AS CURSOR для позиционного удаления записи
CREATE PROCEDURE DELTOWN ( TOWNTODELETE VARCHAR(24)) RETURNS ( TOWN VARCHAR(24), POP INTEGER) AS BEGIN FOR SELECT TOWN, POP FROM TOWNS INTO :TOWN, :POP AS CURSOR TCUR DO BEGIN IF (:TOWN = :TOWNTODELETE) THEN -- Позиционное удаление записи DELETE FROM TOWNS WHERE CURRENT OF TCUR; ELSE SUSPEND; END END
См. также: SELECT, DECLARE ... CURSOR, OPEN, CLOSE, FETCH.
Назначение: Выполнение динамически созданных SQL операторов с возвратом нескольких строк данных.
Доступно в: PSQL.
Синтаксис:
FOR<execute_statement>
DO<compound_statement>
Таблица 6.11. Параметры оператора FOR EXECUTE STATEMENT
Параметр | Описание |
---|---|
execute_statement |
Оператор EXECUTE STATEMENT. |
compound_statement |
Оператор или блок операторов. |
Оператор FOR EXECUTE STATEMENT используется (по аналогии с конструкцией FOR SELECT) для операторов SELECT или EXECUTE BLOCK, возвращающих более одной строки.
Примеры:
Пример 6.18. Использование оператора EXECUTE STATEMENT.
CREATE PROCEDURE DynamicSampleThree ( Q_FIELD_NAME VARCHAR(100), Q_TABLE_NAME VARCHAR(100) ) RETURNS( LINE VARCHAR(32000) ) AS DECLARE VARIABLE P_ONE_LINE VARCHAR(100); BEGIN LINE = ''; FOR EXECUTE STATEMENT 'SELECT T1.' || :Q_FIELD_NAME || ' FROM ' || :Q_TABLE_NAME || ' T1 ' INTO :P_ONE_LINE DO IF (:P_ONE_LINE IS NOT NULL) THEN LINE = :LINE || :P_ONE_LINE || ' '; SUSPEND; END
См. также: EXECUTE STATEMENT.
Назначение: Открытие курсора.
Доступно в: PSQL.
Синтаксис:
OPEN cursor_name
;
Таблица 6.12. Параметры оператора OPEN
Параметр | Описание |
---|---|
cursor_name |
Имя курсора. Курсор с таким именем должен быть предварительно объявлен с помощью оператора DECLARE ... CURSOR. |
Оператор OPEN открывает ранее объявленный курсор, выполняет объявленный в нем оператор SELECT и получает записи из результирующего набора данных. Оператор OPEN применим только к курсорам, объявленным в операторе DECLARE ... CURSOR.
Если в операторе SELECT курсора имеются параметры, то они должны быть объявлены как локальные переменные или входные (выходные) параметры до того как объявлен курсор. При открытии курсора параметру присваивается текущее значение переменной.
Примеры: См. примеры в операторе FETCH.
См. также: FETCH, CLOSE, DECLARE ... CURSOR.
Назначение: Чтение записи из набора данных, связанного с курсором.
Доступно в: PSQL.
Синтаксис:
FETCHcursor_name
INTO [:]var_name
[, [:]var_name
...];
Таблица 6.13. Параметры оператора FETCH
Параметр | Описание |
---|---|
cursor_name |
Имя курсора. Курсор с таким именем должен быть предварительно объявлен с помощью оператора DECLARE ... CURSOR. |
var_name |
PSQL переменная. |
Оператор FETCH выбирает следующую строку данных из результирующего набора данных курсора и присваивает значения столбцов в переменные PSQL. Оператор FETCH применим только к курсорам, объявленным в операторе DECLARE ... CURSOR.
Предложение INTO помещает данные из текущей строки курсора в PSQL переменные.
Для проверки того, что записи набора данных исчерпаны, используется контекстная переменная ROW_COUNT, которая возвращает количество строк выбранных оператором. Если произошло чтение очередной записи из набора данных, то ROW_COUNT равняется единице, иначе нулю.
Примеры:
Пример 6.19. Использования оператора FETCH
SET TERM ^; CREATE OR ALTER PROCEDURE GET_RELATIONS_NAMES RETURNS ( RNAME CHAR(31) ) AS DECLARE C CURSOR FOR (SELECT RDB$RELATION_NAME FROM RDB$RELATIONS); BEGIN OPEN C; WHILE (1 = 1) DO BEGIN FETCH C INTO :RNAME; IF (ROW_COUNT = 0) THEN LEAVE; SUSPEND; END CLOSE C; END^ SET TERM ;^
Пример 6.20. Использования оператора FETCH со вложенными курсорами
EXECUTE BLOCK RETURNS ( SCRIPT BLOB SUB_TYPE TEXT) AS DECLARE VARIABLE FIELDS VARCHAR(8191); DECLARE VARIABLE FIELD_NAME TYPE OF RDB$FIELD_NAME; DECLARE VARIABLE RELATION RDB$RELATION_NAME; DECLARE VARIABLE SRC TYPE OF COLUMN RDB$RELATIONS.RDB$VIEW_SOURCE; -- Объявление именованного курсора DECLARE VARIABLE CUR_R CURSOR FOR ( SELECT RDB$RELATION_NAME, RDB$VIEW_SOURCE FROM RDB$RELATIONS WHERE RDB$VIEW_SOURCE IS NOT NULL); -- Объявление именованного курсора, в котором -- используется локальная переменная DECLARE CUR_F CURSOR FOR ( SELECT RDB$FIELD_NAME FROM RDB$RELATION_FIELDS WHERE -- Важно переменная должна быть объявлена ранее RDB$RELATION_NAME = :RELATION); BEGIN OPEN CUR_R; WHILE (1 = 1) DO BEGIN FETCH CUR_R INTO :RELATION, :SRC; IF (ROW_COUNT = 0) THEN LEAVE; FIELDS = NULL; -- Курсор CUR_F будет использовать значение -- переменной RELATION инициализированной выше OPEN CUR_F; WHILE (1 = 1) DO BEGIN FETCH CUR_F INTO :FIELD_NAME; IF (ROW_COUNT = 0) THEN LEAVE; IF (FIELDS IS NULL) THEN FIELDS = TRIM(FIELD_NAME); ELSE FIELDS = FIELDS || ', ' || TRIM(FIELD_NAME); END CLOSE CUR_F; SCRIPT = 'CREATE VIEW ' || RELATION; IF (FIELDS IS NOT NULL) THEN SCRIPT = SCRIPT || ' (' || FIELDS || ')'; SCRIPT = SCRIPT || ' AS ' || ASCII_CHAR(13); SCRIPT = SCRIPT || SRC; SUSPEND; END CLOSE CUR_R; END
См. также: OPEN, CLOSE, DECLARE ... CURSOR.
Назначение: Закрытие курсора.
Доступно в: PSQL.
Синтаксис:
CLOSE cursor_name
;
Таблица 6.14. Параметры оператора CLOSE
Параметр | Описание |
---|---|
cursor_name |
Имя открытого курсора. Курсор с таким именем должен быть предварительно объявлен с помощью оператора DECLARE ... CURSOR. |
Оператор CLOSE закрывает открытый курсор. Любые все ещё открытые курсоры будут автоматически закрыты после выполнения кода триггера, хранимой процедуры или выполнимого блока, в пределах кода которого он был открыт. Оператор CLOSE применим только к курсорам, объявленным в операторе DECLARE ... CURSOR.
Примеры: См. примеры в операторе FETCH.
См. также: FETCH, OPEN, DECLARE ... CURSOR.
Назначение: Выполнение оператора или блока операторов в автономной транзакции.
Доступно в: PSQL.
Синтаксис:
IN AUTONOMOUS TRANSACTION DO <compound_statement>
Таблица 6.15. Параметры оператора IN AUTONOMOUS TRANSACTION
Параметр | Описание |
---|---|
compound_statement |
Оператор или блок операторов. |
Оператор IN AUTONOMOUS TRANSACTION позволяет выполнить оператор или блок операторов в автономной транзакции. Код, работающий в автономной транзакции, будет подтверждаться сразу же после успешного завершения независимо от состояния родительской транзакции. Это бывает нужно, когда определённые действия не должны быть отменены, даже в случае возникновения ошибки в родительской транзакции.
Автономная транзакция имеет тот же уровень изоляции, что и родительская транзакция. Любое исключение, вызванное или появившееся в блоке кода автономной транзакции, приведёт к откату автономной транзакции и отмене всех внесённых изменений. Если код будет выполнен успешно, то автономная транзакция будет подтверждена.
Примеры:
Пример 6.21. Использование автономных транзакций
/** * Использование автономной транзакции в триггере на событие подключения к базе * данных для регистрации всех попыток соединения, в том числе и неудачных. */ CREATE TRIGGER TR_CONNECT ON CONNECT AS BEGIN -- Все попытки соединения с БД сохраняем в журнал IN AUTONOMOUS TRANSACTION DO INSERT INTO LOG(MSG) VALUES ('USER ' || CURRENT_USER || ' CONNECTS.'); IF (CURRENT_USER IN (SELECT USERNAME FROM BLOCKED_USERS)) THEN BEGIN -- Сохраняем в журнал, что попытка соединения -- с БД оказалась неудачной -- и отправляем сообщение о событии IN AUTONOMOUS TRANSACTION DO BEGIN INSERT INTO LOG(MSG) VALUES ('USER ' || CURRENT_USER || ' REFUSED.'); POST_EVENT 'CONNECTION ATTEMPT' || ' BY BLOCKED USER!'; END -- теперь вызываем исключение EXCEPTION EX_BADUSER; END END
См. также: Управление транзакциями.
Назначение: Посылка события (сообщения) клиентским приложениям.
Доступно в: PSQL.
Синтаксис:
POST_EVENT event_name
Таблица 6.16. Параметры оператора POST_EVENT
Параметр | Описание |
---|---|
event_name |
Имя события, ограничено 64 символами. |
Оператор POST_EVENT сообщает о событии менеджеру событий, который сохраняет его в таблице событий. При подтверждении транзакции менеджер событий информирует приложения, ожидающие это событие.
Имя события это своего рода код или короткое сообщение, выбор за вами, т.к. это просто строка длинной до 127 байт.
В качестве имени события может быть использован строковый литерал, переменная или любое правильное SQL выражение.
Примеры:
Пример 6.22. Оповещёние приложения о вставке записи в таблицу SALES
SET TERM ^; CREATE TRIGGER POST_NEW_ORDER FOR SALES ACTIVE AFTER INSERT POSITION 0 AS BEGIN POST_EVENT 'new_order'; END^ SET TERM ;^
В Firebird существуют PSQL операторы для обработки ошибок и исключений в модулях. Существует множество встроенных исключений, которые возникают в случае возникновения стандартных ошибок при работе с DML и DDL операторами.
Исключение представляет собой сообщение, которое генерируется, когда возникает ошибка.
Все обрабатываемые Firebird исключения имеют заранее определённые числовые (символьные) значение для контекстных переменных и связанные с ними тексты сообщений. Сообщения об ошибке написаны по умолчанию на английском языке. Существуют и локализованные сборки СУБД, в которых сообщения об ошибках переведены на другие языки.
Полный список системных исключений вы можете найти в приложении Обработка ошибок, коды и сообщения:
Пользовательские исключения могут быть объявлены в базе данных как постоянные объекты и вызваны из PSQL кода для сообщения об ошибке при нарушении некоторых бизнес правил. Текст пользовательского исключения ограничен 1021 байтом. Подробности см. CREATE EXCEPTION.
В коде PSQL исключения обрабатываются при помощи оператора WHEN. Если исключение будет обработано в вашем коде, то вы обеспечите исправление или обход ошибки и позволите продолжить выполнение, — то клиенту не возвращается никакого сообщения об исключении.
Исключение приводит к прекращению выполнения в блоке. Вместо того чтобы передать выполнение на конечный оператор END, теперь процедура отыскивает уровни во вложенных блоках, начиная с блока где была вызвана ошибка, и переходит на внешние блоки, чтобы найти код обработчика, который "знает" о таком исключении. Она отыскивает первый оператор WHEN, который может обработать эту ошибку.
Назначение: Возбуждение пользовательского исключения или повторный вызов исключения.
Доступно в: PSQL.
Синтаксис:
EXCEPTIONexception_name
[custom_message
]
Таблица 6.17. Параметры оператора EXCEPTION
Параметр | Описание |
---|---|
exception_name |
Имя исключения. |
custom_message |
Альтернативный текст сообщения, выдаваемый при возникновении исключения. Максимальная длина текстового сообщения составляет 1021 байт. |
Оператор EXCEPTION возбуждает пользовательское исключение с указанным именем. При возбуждении исключения можно также указать альтернативный текст сообщения, который заменит текст сообщения заданным при создании исключения.
Исключение может быть обработано в операторе WHEN ... DO. Если пользовательское исключение не было обработано в триггере или в хранимой процедуре, то действия, выполненные внутри этой хранимой процедуры (триггера) отменяются, а вызвавшая программа получает текст, заданный при создании исключения или альтернативный текст сообщения.
В блоке обработки исключений (и только в нем), вы можете повторно вызвать пойманное исключение или ошибку, вызывая оператор EXCEPTION без параметров. Вне блока с исключением такой вызов не имеет никакого эффекта.
Примеры:
Пример 6.23. Вызов исключения
CREATE OR ALTER PROCEDURE SHIP_ORDER ( PO_NUM CHAR(8)) AS DECLARE VARIABLE ord_stat CHAR(7); DECLARE VARIABLE hold_stat CHAR(1); DECLARE VARIABLE cust_no INTEGER; DECLARE VARIABLE any_po CHAR(8); BEGIN SELECT s.order_status, c.on_hold, c.cust_no FROM sales s, customer c WHERE po_number = :po_num AND s.cust_no = c.cust_no INTO :ord_stat, :hold_stat, :cust_no; /* Этот заказ уже отправлен на поставку. */ IF (ord_stat = 'shipped') THEN EXCEPTION order_already_shipped; /* Другие операторы */ END
Пример 6.24. Вызов исключения с заменой исходного сообщения альтернативным
CREATE OR ALTER PROCEDURE SHIP_ORDER ( PO_NUM CHAR(8)) AS DECLARE VARIABLE ord_stat CHAR(7); DECLARE VARIABLE hold_stat CHAR(1); DECLARE VARIABLE cust_no INTEGER; DECLARE VARIABLE any_po CHAR(8); BEGIN SELECT s.order_status, c.on_hold, c.cust_no FROM sales s, customer c WHERE po_number = :po_num AND s.cust_no = c.cust_no INTO :ord_stat, :hold_stat, :cust_no; /* Этот заказ уже отправлен на поставку. */ IF (ord_stat = 'shipped') THEN EXCEPTION order_already_shipped 'Order status is "' || ord_stat || '"'; /* Другие операторы */ END
Пример 6.25. Регистрация ошибке в журнале и повторное её возбуждение в блоке WHEN
CREATE PROCEDURE ADD_COUNTRY ( ACountryName COUNTRYNAME, ACurrency VARCHAR(10) ) AS BEGIN INSERT INTO country (country, currency) VALUES (:ACountryName, :ACurrency); WHEN ANY DO BEGIN -- Записываем ошибку в журнал IN AUTONOMOUS TRANSACTION DO INSERT INTO ERROR_LOG (PSQL_MODULE, GDS_CODE, SQL_CODE, SQL_STATE) VALUES ('ADD_COUNTRY', GDSCODE, SQLCODE, SQLSTATE); -- Повторно возбуждаем ошибку EXCEPTION; END END
См. также: CREATE EXCEPTION, WHEN ... DO.
Назначение: Обработка ошибок.
Доступно в: PSQL.
Синтаксис:
WHEN {<error>
[,<error>
...] | ANY} DO<compound_statement>
<error>
::= { EXCEPTIONexception_name
| SQLCODEnumber
| GDSCODEerrcode
}
Таблица 6.18. Параметры оператора WHEN ... DO
Параметр | Описание |
---|---|
exception_name |
Имя исключения. |
number |
Код ошибки SQLCODE. |
errcode |
Символическое имя ошибки GDSCODE. |
compound_statement |
Оператор или блок операторов. |
Оператор WHEN ... DO используется для обработки ошибочных ситуаций и пользовательских исключений. Оператор перехватывает все ошибки и пользовательские исключения, перечисленные после ключевого слова WHEN. Если после ключевого слова WHEN указано ключевое слово ANY, то оператор перехватывает любые ошибки и пользовательские исключения, даже если они уже были обработаны в вышестоящем WHEN блоке.
Оператор WHEN ... DO должен находиться в самом конце блока операторов перед оператором END.
После ключевого слова DO следует оператор или блок операторов, заключённый в операторные скобки BEGIN и END, которые выполняют некоторую обработку возникшей ситуации. В этом операторе (блоке операторов) доступны контекстные переменные SQLCODE, GDSCODE, SQLSTATE. Там же разрешён оператор повторного вызова ошибки или исключительной ситуации EXCEPTION (без параметров).
После предложения WHEN GDSCODE вы должны использовать символьные имена -
такие, как grant_obj_notfound
и т.д. Но в
операторе или блоке операторов после предложения DO доступна контекстная
переменная GDSCODE, которая содержит целое число. Для сравнения его с
определённой ошибкой вы должны использовать числовое значение, например,
335544551 для grant_obj_notfound
.
Оператор WHEN ... DO вызывается только в том случае, если произошло одно из указанных в его условии событий. В случае выполнения оператора (даже если в нем фактически не было выполнено никаких действий) ошибка или пользовательское исключение не прерывает и не отменяет действий триггера или хранимой процедуры, где был выдан этот оператор, работа продолжается, как если бы никаких исключительных ситуаций не было. Однако в этом случае будет отменено действие DML оператора (SELECT, INSERT, UPDATE, DELETE, MERGE), который вызвал ошибку и все ниже находящиеся операторы в том же блоке операторов не будут выполнены.
Если ошибка вызвана не одним из DML операторов (SELECT, INSERT, UPDATE, DELETE, MERGE), то будет отменен не только оператор вызвавший ошибку, а весь блок операторов. Кроме того, действия в операторе WHEN ... DO так же будут откачены. Это относится также и к оператору выполнения хранимой процедуры EXECUTE PROCEDURE. Подробнее смотри в CORE-4483.
Оператор перехватывает ошибки и исключения в текущем блоке операторов. Он также перехватывает подобные ситуации во вложенных блоках, если эти ситуации не были в них обработаны.
Оператор WHEN ... DO видит все изменения, произведённые до оператора вызвавшего ошибку. Однако если вы попытаетесь запротоколировать их в автономной транзакции, то эти изменения будут не доступны, поскольку на момент старта автономной транзакции, транзакция, в которой произошли эти изменения, не подтверждена.
При обработке исключений, иногда требуется обработать исключение, записав при это сообщение в журнал об ошибке, и продолжить выполнение пропустив ошибочную запись. Журнал может быть записан в обычную таблицу, но существует следующая проблема: записи журнала исчезнут, если выполнение модуля остановлена и транзакция откачена. Использование внешних таблиц решает эту проблему, поскольку данные записанные в неё не зависят от транзакции. Внешний файл будет сохранён независимо от того завершено ли выполнение процесса целиком или нет.
Примеры:
Пример 6.26. Замена стандартной ошибки своей.
CREATE EXCEPTION COUNTRY_EXIST ''; SET TERM ^; CREATE PROCEDURE ADD_COUNTRY ( ACountryName COUNTRYNAME, ACurrency VARCHAR(10) ) AS BEGIN INSERT INTO country (country, currency) VALUES (:ACountryName, :ACurrency); WHEN SQLCODE -803 DO EXCEPTION COUNTRY_EXIST 'Такая страна уже добавлена!'; END^ SET TERM ^;
Пример 6.27. Регистрация ошибке в журнале и повторное её возбуждение в блоке WHEN.
CREATE PROCEDURE ADD_COUNTRY ( ACountryName COUNTRYNAME, ACurrency VARCHAR(10) ) AS BEGIN INSERT INTO country (country, currency) VALUES (:ACountryName, :ACurrency); WHEN ANY DO BEGIN -- Записываем ошибку в журнал IN AUTONOMOUS TRANSACTION DO INSERT INTO ERROR_LOG (PSQL_MODULE, GDS_CODE, SQL_CODE, SQL_STATE) VALUES ('ADD_COUNTRY', GDSCODE, SQLCODE, SQLSTATE); -- Повторно возбуждаем ошибку EXCEPTION; END END
Пример 6.28. Обработка в одном WHEN … DO блоке нескольких ошибок
... WHEN GDSCODE GRANT_OBJ_NOTFOUND, GDSCODE GRANT_FLD_NOTFOUND, GDSCODE GRANT_NOPRIV, GDSCODE GRANT_NOPRIV_ON_BASE DO BEGIN EXECUTE PROCEDURE LOG_GRANT_ERROR(GDSCODE); EXIT; END ...
См. также: EXCEPTION, Коды ошибок SQLSTATE и их описание, Коды ошибок GDSCODE их описание, и SQLCODE, GDSCODE, SQLCODE, SQLSTATE.
Доступно в: DSQL, PSQL.
Синтаксис:
CURRENT_CONNECTION
Тип возвращаемого результата: INTEGER
Переменная CURRENT_CONNECTION хранит уникальный идентификатор текущего соединения. Значение переменной хранится в странице заголовка базы и сбрасывается после restore. Переменная увеличивается на единицу при каждом последующем соединении с базой данных (соединения также могут быть внутренними вызванными самим ядром). Следовательно, переменная показывает количество подключений произошедших к базе после её восстановления (или после её создания).
Примеры:
См. также: CURRENT_TRANSACTION.
Доступно в: DSQL, PSQL, ESQL.
Синтаксис:
CURRENT_DATE
Тип возвращаемого результата: DATE
Переменная CURRENT_DATE возвращает текущую дату сервера.
Примеры:
Пример 7.2. Использование переменной CURRENT_DATE
CREATE DOMAIN DDATE_DNN AS DATE DEFAULT CURRENT_DATE NOT NULL
См. также: 'TODAY', CURRENT_TIMESTAMP, CURRENT_TIME.
Доступно в: DSQL, PSQL.
Синтаксис:
CURRENT_ROLE
Тип возвращаемого результата: VARCHAR(31)
Контекстная переменная CURRENT_ROLE служит для определения роли, с которой произошло подключение к базе данных. В случае если произошло подключение без указания роли, переменная принимает значение NONE.
Примеры:
Такое же значение можно будет получить и в результате выполнения запроса:
SELECT RDB$GET_CONTEXT ('SYSTEM', 'CURRENT_ROLE') FROM RDB$DATABASE;
См. также: RDB$GET_CONTEXT.
Доступно в: DSQL, PSQL, ESQL.
Синтаксис:
CURRENT_TIME [(<precision>
)]<precision>
::= 0 | 1 | 2 | 3
Параметры контекстной переменной CURRENT_TIME
precision
Точность. Значение по умолчанию 0. Не поддерживается в ESQL.
Тип возвращаемого результата: TIME
Переменная CURRENT_TIME возвращает текущее время сервера. Точность определяет, сколько учитывать знаков после запятой в долях секунды. Точность по умолчанию равна 0.
В блоке кода PSQL (процедура, триггер, исполняемый блок) значение CURRENT_TIME не меняется по мере выполнения. При вызове вложенного кода, значение также не изменится и будет равно значению в коде самого верхнего уровня. Для определения реального времени используйте другие переменные, например, 'NOW' (с полным приведением типа данных).
Примеры:
Пример 7.4. Использование переменной CURRENT_TIME
SELECT CURRENT_TIME(2) FROM RDB$DATABASE; -- результат будет (например) 23:35:33.1200
Firebird 4.0 будет поддерживать часовые пояса.
В рамках этой поддержки будет возникать несовместимость с выражением
CURRENT_TIME
предыдущих версий.
В Firebird 4.0 выражение CURRENT_TIME
будет возвращать тип данных
TIME WITH TIME ZONE
.
Для того чтобы ваши запросы были совместимы с кодом баз данных будующих версий,
начиная с Firebird 2.5.9 вы можете использовать выражение LOCALTIME
. В 2.5
LOCALTIME
является синонимом CURRENT_TIME
.
В Firebird 4.0 LOCALTIME
будет продолжать работать точно так же как
сейчас, в то время как CURRENT_TIME
будет возвращать другой тип
данных.
Вам не следует начинать использовать LOCALTIME
, если можете произвести
даунгрейд вашей базы данных до версии 2.5.8 или другой более младшей версии, поскольку
старые версии Firebird не смогут распознать новые выражения.
См. также: LOCALTIME, 'NOW', CURRENT_TIMESTAMP, CURRENT_DATE.
Доступно в: DSQL, PSQL, ESQL.
Синтаксис:
CURRENT_TIMESTAMP [(<precision>
)]<precision>
::= 0 | 1 | 2 | 3
Параметры контекстной переменной CURRENT_TIMESTAMP
precision
Точность. Значение по умолчанию 3. Не поддерживается в ESQL.
Тип возвращаемого результата: TIMESTAMP
Переменная CURRENT_TIMESTAMP возвращает текущую дату и время сервера. Точность определяет, сколько учитывать знаков после запятой в долях секунды. Точность по умолчанию равна 3.
В блоке кода PSQL (процедура, триггер, исполняемый блок) значение CURRENT_TIMESTAMP не меняется по мере выполнения. При вызове вложенного кода, значение также не изменится и будет равно значению в коде самого верхнего уровня. Для определения реального времени используйте другие переменные, например, 'NOW' (с полным приведением типа данных).
Примеры:
Пример 7.5. Использование переменной CURRENT_TIMESTAMP
SELECT CURRENT_TIMESTAMP(2) FROM RDB$DATABASE; -- результат будет (например) 02.03.2014 23:35:33.1200
Firebird 4.0 будет поддерживать часовые пояса.
В рамках этой поддержки будет возникать несовместимость с выражением
CURRENT_TIMESTAMP
предыдущих версий.
В Firebird 4.0 выражение CURRENT_TIMESTAMP
будет возвращать тип данных
TIMESTAMP WITH TIME ZONE
.
Для того чтобы ваши запросы были совместимы с кодом баз данных будующих версий,
начиная с Firebird 2.5.9 вы можете использовать выражение LOCALTIMESTAMP
. В
2.5 LOCALTIMESTAMP
является синонимом CURRENT_TIMESTAMP
.
В Firebird 4.0 LOCALTIMESTAMP
будет продолжать работать точно так же как
сейчас, в то время как CURRENT_TIMESTAMP
будет возвращать другой тип
данных.
Вам не следует начинать использовать LOCALTIMESTAMP
, если можете
произвести даунгрейд вашей базы данных до версии 2.5.8 или другой более младшей версии,
поскольку старые версии Firebird не смогут распознать новые выражения.
См. также: LOCALTIMESTAMP, 'NOW', CURRENT_TIME, CURRENT_DATE.
Доступно в: DSQL, PSQL.
Синтаксис:
CURRENT_TRANSACTION
Тип возвращаемого результата: INTEGER
Переменная CURRENT_TRANSACTION содержит уникальный номер текущей транзакции.
Значение CURRENT_TRANSACTION хранится в странице заголовка базы данных и сбрасывается в 0 после восстановления (или создания базы). Оно увеличивается при старте новой транзакции.
Примеры:
Пример 7.6. Использование переменной CURRENT_TRANSACTION
SELECT CURRENT_TRANSACTION FROM RDB$DATABASE; NEW.TRANS_ID = CURRENT_TRANSACTION;
См. также: CURRENT_CONNECTION, RDB$GET_CONTEXT.
Доступно в: DSQL, PSQL.
Синтаксис:
CURRENT_USER
Тип возвращаемого результата: VARCHAR(31)
Переменная CURRENT_USER содержит имя текущего подключенного пользователя базы данных.
Примеры:
См. также: USER, CURRENT_ROLE.
Доступно в: PSQL.
Синтаксис:
DELETING
Тип возвращаемого результата: BOOLEAN
Контекстная переменная DELETING доступна только в коде табличных триггеров. Используется в триггерах на несколько типов событий и показывает, что триггер сработал при выполнении операции DELETE.
Примеры:
Пример 7.8. Использование переменной DELETING
... IF (DELETING) THEN BEGIN INSERT INTO REMOVED_CARS ( ID, MAKE, MODEL, REMOVED) VALUES ( OLD.ID, OLD.MAKE, OLD.MODEL, CURRENT_TIMESTAMP); END ...
Доступно в: PSQL.
Синтаксис:
GDSCODE
Тип возвращаемого результата: INTEGER
В блоке обработки ошибок "WHEN ... DO" контекстная переменная GDSCODE содержит числовое представление текущего кода ошибки Firebird. До версии Firebird 2.0 GDSCODE можно было получить только с использованием конструкции WHEN GDSCODE. Теперь эту контекстную переменную можно также использовать в блоках WHEN ANY, WHEN SQLCODE и WHEN EXCEPTION при условии, что код ошибки соответствует коду ошибки Firebird. Вне обработчика ошибок GDSCODE всегда равен 0. Вне PSQL GDSCODE не существует вообще.
Примеры:
Пример 7.9. Использование переменной GDSCODE
... WHEN GDSCODE GRANT_OBJ_NOTFOUND, GDSCODE GRANT_FLD_NOTFOUND, GDSCODE GRANT_NOPRIV, GDSCODE GRANT_NOPRIV_ON_BASE DO BEGIN EXECUTE PROCEDURE LOG_GRANT_ERROR(GDSCODE); EXIT; END ...
Обратите внимание: после, WHEN GDSCODE вы должны использовать символьные имена —
такие, как grant_obj_notfound
и т.д. Но контекстная переменная
GDSCODE — целое число. Для сравнения его с определённой ошибкой вы должны использовать
числовое значение, например, 335544551 для
grant_obj_notfound
.
Доступно в: PSQL.
Синтаксис:
INSERTING
Тип возвращаемого результата: BOOLEAN
Контекстная переменная INSERTING доступна только коде табличных триггеров. Используется в триггерах на несколько типов событий и показывает, что триггер сработал при выполнении операции INSERT.
Примеры:
Пример 7.10. Использование переменной INSERTING
...
IF (INSERTING OR UPDATING) THEN
BEGIN
IF (NEW.SERIAL_NUM IS NULL) THEN
NEW.SERIAL_NUM = GEN_ID (GEN_SERIALS, 1);
END
...
Доступно в: DSQL, PSQL, ESQL.
Синтаксис:
LOCALTIME [(<precision>
)]<precision>
::= 0 | 1 | 2 | 3
Таблица 7.1. Параметры контекстной переменной LOCALTIME
Параметр | Описание |
---|---|
precision |
Точность. Значение по умолчанию 0. Не поддерживается в ESQL. |
Тип возвращаемого результата: TIME
Переменная LOCALTIME возвращает текущее время сервера. Точность определяет, сколько учитывать знаков после запятой в долях секунды. Точность по умолчанию равна 0.
В блоке кода PSQL (процедура, триггер, исполняемый блок) значение LOCALTIME не меняется по мере выполнения. При вызове вложенного кода, значение также не изменится и будет равно значению в коде самого верхнего уровня. Для определения реального времени используйте другие переменные, например 'NOW' (с полным приведением типа данных).
Примеры:
Пример 7.11. Использование переменной LOCALTIME
SELECT LOCALTIME(2) FROM RDB$DATABASE; -- результат будет (например) 23:35:33.1200
Firebird 4.0 будет поддерживать часовые пояса.
В рамках этой поддержки будет возникать несовместимость с выражением
CURRENT_TIME
предыдущих версий.
В Firebird 4.0 выражение CURRENT_TIME
будет возвращать тип данных
TIME WITH TIME ZONE
.
Для того чтобы ваши запросы были совместимы с кодом баз данных будующих версий,
начиная с Firebird 2.5.9 вы можете использовать выражение LOCALTIME
. В 2.5
LOCALTIME
является синонимом CURRENT_TIME
.
В Firebird 4.0 LOCALTIME
будет продолжать работать точно так же как
сейчас, в то время как CURRENT_TIME
будет возвращать другой тип
данных.
Вам не следует начинать использовать LOCALTIME
, если можете произвести
даунгрейд вашей базы данных до версии 2.5.8 или другой более младшей версии, поскольку
старые версии Firebird не смогут распознать новые выражения.
См. также: CURRENT_TIME, 'NOW', CURRENT_TIMESTAMP, CURRENT_DATE.
Доступно в: DSQL, PSQL, ESQL.
Синтаксис:
LOCALTIMESTAMP [(<precision>
)]<precision>
::= 0 | 1 | 2 | 3
Таблица 7.2. Параметры контекстной переменной LOCALTIMESTAMP
Параметр | Описание |
---|---|
precision |
Точность. Значение по умолчанию 3. Не поддерживается в ESQL. |
Тип возвращаемого результата: TIMESTAMP
Переменная LOCALTIMESTAMP возвращает текущую дату и время сервера. Точность определяет, сколько учитывать знаков после запятой в долях секунды. Точность по умолчанию равна 3.
В блоке кода PSQL (процедура, триггер, исполняемый блок) значение LOCALTIMESTAMP не меняется по мере выполнения. При вызове вложенного кода, значение также не изменится и будет равно значению в коде самого верхнего уровня. Для определения реального времени используйте другие переменные, например 'NOW' (с полным приведением типа данных).
Примеры:
Пример 7.12. Использование переменной LOCALTIMESTAMP
SELECT LOCALTIMESTAMP(2) FROM RDB$DATABASE; -- результат будет (например) 02.03.2014 23:35:33.1200
Firebird 4.0 будет поддерживать часовые пояса.
В рамках этой поддержки будет возникать несовместимость с выражением
CURRENT_TIMESTAMP
предыдущих версий.
В Firebird 4.0 выражение CURRENT_TIMESTAMP
будет возвращать тип данных
TIMESTAMP WITH TIME ZONE
.
Для того чтобы ваши запросы были совместимы с кодом баз данных будующих версий,
начиная с Firebird 2.5.9 вы можете использовать выражение LOCALTIMESTAMP
. В
2.5 LOCALTIMESTAMP
является синонимом CURRENT_TIMESTAMP
.
В Firebird 4.0 LOCALTIMESTAMP
будет продолжать работать точно так же как
сейчас, в то время как CURRENT_TIMESTAMP
будет возвращать другой тип
данных.
Вам не следует начинать использовать LOCALTIMESTAMP
, если можете
произвести даунгрейд вашей базы данных до версии 2.5.8 или другой более младшей версии,
поскольку старые версии Firebird не смогут распознать новые выражения.
См. также: CURRENT_TIMESTAMP, 'NOW', CURRENT_TIME, CURRENT_DATE.
Доступно в: PSQL.
Синтаксис:
NEW
Контекстная переменная NEW доступна только в коде табличных триггеров. Значение NEW содержит новые значения полей данных, которое возникли в базе во время операции обновления или вставки.
В AFTER триггерах переменная доступна только для чтения.
Для табличных триггеров, срабатывающих на несколько типов событий, переменная NEW доступна всегда. Однако в случае если триггер сработал на операцию удаления, то для него новая версия данных не имеет смысла. В этой ситуации чтение переменной NEW всегда вернёт NULL.
Попытка записи в переменную NEW в AFTER триггере вызовет исключение в коде.
Примеры:
Пример 7.13. Использование переменной NEW
...
IF (NEW.SERIAL_NUM IS NULL) THEN
NEW.SERIAL_NUM = GEN_ID (GEN_SERIALS, 1);
...
См. также: OLD.
Доступно в: DSQL, PSQL, ESQL.
Синтаксис:
'NOW'
Не является переменной, а является строковым литералом. При использовании преобразования типов данных, например, с помощью функции CAST() в тип даты/времени позволяет получить текущую дату и/или время. Значение "после запятой" у переменной показывают число миллисекунд. Точность составляет 3 знака после запятой (миллисекунды). Написание 'NOW' не зависит от регистра, при преобразовании в дату функция игнорирует все пробелы слева и справа от слова.
Поскольку 'NOW' всегда возвращает актуальные значения даты и времени при использовании CAST() для приведения типов данных она может использоваться для измерения временных интервалов и скорости выполнения кода в процедурах, триггерах и блоках кода PSQL.
Примеры:
Пример 7.14. Использование переменной 'NOW'
SELECT CAST('Now' AS DATE) FROM rdb$database; -- возвратит текущую дату, например 2014-10-03 SELECT CAST('now' AS TIME) FROM rdb$database; -- возвратит текущее время, например 14:20:19.6170 SELECT CAST('NOW' AS TIMESTAMP) FROM rdb$database; -- возвратит текущую дату и время, например 2014-10-03 14:20:19.6170 -- при использовании короткого "C-Style" литерала -- будет возращено дата и время на момент подготовки запроса SELECT TIMESTAMP 'NOW' FROM rdb$database;
Пример 7.15. Использование 'NOW' измерения длительности выполнения кода
EXECUTE BLOCK RETURNS (ms BIGINT) AS DECLARE VARIABLE t1 TIME; DECLARE VARIABLE n BIGINT; BEGIN t1 = CAST('now' AS TIME); /* Долгая операция */ SELECT COUNT(*) FROM rdb$types, rdb$types, rdb$types INTO n; /*======*/ ms = DATEDIFF(MILLISECOND FROM t1 TO CAST('now' AS TIME)); SUSPEND; END
Не рекомендуем использовать сокращённые выражения для литерала 'NOW'. Использование таких выражений в компилируемом PSQL приводит к тому, что значение "замораживается" на момент компиляции, и в результате возвращается не актуальное значение. В Firebird 4.0 сокращённые выражения для таких строковых литералов будут запрещены, однако вы по прежнему сможете использовать их при приведении типа оператором CAST. Смотри также Литералы даты и времени.
См. также: CURRENT_TIMESTAMP, CURRENT_DATE, CURRENT_TIME, TODAY, TOMORROW, YESTERDAY, Преобразование строк в дату и время.
Доступно в: PSQL.
Синтаксис:
OLD
Контекстная переменная OLD доступна только коде триггеров. Значения, содержащееся в OLD, хранит прошлые значения полей, которые были в базе до операции изменения или удаления.
Переменная OLD доступна только для чтения.
Для табличных триггеров, срабатывающих на несколько типов событий, значения для переменной OLD всегда возможны. Однако для триггеров, сработавших на вставку записи, значение данной переменной не имеет смысла, поэтому в этой ситуации чтение OLD возвратит NULL, а попытка записи в неё вызовет исключение в коде.
Примеры:
Пример 7.16. Использование переменной OLD
... IF (NEW.QUANTITY IS DISTINCT FROM OLD.QUANTITY) THEN DELTA = NEW.QUANTITY - OLD.QUANTITY; ...
См. также: NEW.
Доступно в: PSQL.
Синтаксис:
ROW_COUNT
Тип возвращаемого результата: INTEGER
Контекстная переменная ROW_COUNT содержит число строк, затронутых последним оператором DML (INSERT, UPDATE, DELETE, SELECT или FETCH) в текущем триггере, хранимой процедуре или исполняемом блоке.
Поведение с SELECT и FETCH:
После выполнения singleton SELECT запроса (запроса, который может вернуть не более одной строки данных), ROW_COUNT равна 1, если была получена строка данных и 0 в противном случае;
В цикле FOR SELECT переменная ROW_COUNT увеличивается на каждой итерации (начиная с 0 в качестве первого значения);
После выборки (FETCH) из курсора, ROW_COUNT равна 1, если была получена строка данных и 0 в противном случае. Выборка нескольких записей из одного курсора не увеличивает ROW_COUNT после 1.
Переменная ROW_COUNT не может быть использована для определения количества строк, затронутых при выполнении операторов EXECUTE STATEMENT или EXECUTE PROCEDURE. Для оператора MERGE переменная ROW_COUNT будет содержать 0 или 1, даже если было затронуто более записей
Не используйте переменную ROW_COUNT внутри DML операторов. Дело в том, что эта переменная сбрасывает своё значение в 0 перед началом выполнения любого DML оператора, а потому вы можете получить не то что ожидаете.
... UPDATE t2 SET evt='upd', old_id = old.id, old_x = old.x, new_id = new.id, new_x = new.x WHERE new_id = old.id; INSERT INTO t2log(evt, affected_rows) VALUES('upd', ROW_COUNT); ...
В вышеприведённом примере в столбец affected_rows будут записаны нулевые значения, даже если оператором UPDATE были затронуты строки. Для того, чтобы исправить эту ошибку, необходимо сохранить значение контекстной переменной ROW_COUNT в локальную переменную PSQL модуля и использовать эту локальную переменную в DML операторе.
... DECLARE rc INT; ... UPDATE t2 SET evt='upd', old_id = old.id, old_x = old.x, new_id = new.id, new_x = new.x WHERE new_id = old.id; rc = ROW_COUNT; INSERT INTO t2log(evt, affected_rows) VALUES('upd', rc); ...
Примеры:
Пример 7.17. Использование переменной ROW_COUNT
... UPDATE Figures SET Number = 0 WHERE id = :id; IF (row_count = 0) THEN INSERT INTO Figures (id, Number) VALUES (:id, 0); ...
Доступно в: PSQL.
Синтаксис:
SQLCODE
Тип возвращаемого результата: INTEGER
В блоках обработки ошибок "WHEN ... DO" контекстная переменная SQLCODE содержит текущий код ошибки SQL. До Firebird 2.0 значение SQLCODE можно было получить только в блоках обработки ошибок WHEN SQLCODE и WHEN ANY. Теперь она может быть отлична от нуля в блоках WHEN GDSCODE и WHEN EXCEPTION при условии, что ошибка, вызвавшее срабатывание блока, соответствует коду ошибки SQL. Вне обработчиков ошибок SQLCODE всегда равен 0, а вне PSQL не существует вообще.
Примеры:
Пример 7.18. Использование переменной SQLCODE
... WHEN ANY DO BEGIN IF (SQLCODE <> 0) THEN MSG = 'Обнаружена ошибка SQL!'; ELSE MSG = 'Ошибки нет!'; EXCEPTION EX_CUSTOM MSG; END ...
Доступно в: PSQL.
Синтаксис:
SQLSTATE
Тип возвращаемого результата: CHAR(5)
В блоках обработки ошибок "WHEN ... DO" контекстная переменная SQLSTATE переменная содержит 5 символов SQL-2003 — совместимого кода состояния, переданного оператором, вызвавшим ошибку. Вне обработчиков ошибок SQLSTATE всегда равен '00000', а вне PSQL не существует вообще.
SQLSTATE предназначен для замены SQLCODE. Последняя, в настоящее время устарела и буден удалена будущих версиях Firebird;
Firebird 2.5 не поддерживает синтаксис "WHEN SQLSTATE ... DO". Используйте обработчик блока WHEN ANY для проверки значения переменной SQLSTATE;
Любой код SQLSTATE состоит из двух символов класса и трёх символов подкласса. Класс 00 (успешное выполнение), 01 (предупреждение) и 02 (нет данных) представляют собой условия завершения. Каждый код статуса вне этих классов является исключением. Поскольку классы 00, 01 и 02 не вызывают ошибку, они никогда не будут обнаруживаться в переменной SQLSTATE.
Примеры:
Пример 7.19. Использование переменной SQLSTATE
WHEN ANY DO BEGIN MSG = CASE SQLSTATE WHEN '22003' THEN 'Число вышло за пределы диапазона!' WHEN '22012' THEN 'Деление на ноль!' WHEN '23000' THEN 'Нарушение ограничения целостности!' ELSE 'Ошибок нет! SQLSTATE = ' || SQLSTATE; END; EXCEPTION EX_CUSTOM MSG; END
См. также: GDSCODE, SQLCODE, Коды ошибок SQLSTATE и их описание.
Доступно в: DSQL, PSQL, ESQL.
Синтаксис:
'TODAY'
Не является переменной, а является строковым литералом. При использовании преобразования типов данных, например, с помощью функции CAST() в тип даты/времени позволяет получить текущую дату. Написание 'TODAY' не зависит от регистра, при преобразовании в дату функция игнорирует все пробелы слева и справа от слова.
Примеры:
Пример 7.20. Использование переменной 'TODAY'
SELECT CAST('Today' AS DATE) FROM rdb$database; -- возвратит дату на сегодня, например 2014-10-03 SELECT CAST('TODAY' AS TIMESTAMP) FROM rdb$database; -- возвратит дату на сегодня, например 2014-10-03 00:00:00.0000 -- при использовании короткого "C-Style" литерала -- будет возращена дата подготовки запроса SELECT DATE 'TODAY' FROM rdb$database;
Не рекомендуем использовать сокращённые выражения для литерала 'TODAY'. Использование таких выражений в компилируемом PSQL приводит к тому, что значение "замораживается" на момент компиляции, и в результате возвращается не актуальное значение. В Firebird 4.0 сокращённые выражения для таких строковых литералов будут запрещены, однако вы по прежнему сможете использовать их при приведении типа оператором CAST. Смотри также Литералы даты и времени.
См. также: CURRENT_DATE, TOMORROW, YESTERDAY, Преобразование строк в дату и время.
Доступно в: DSQL, PSQL, ESQL.
Синтаксис:
'TOMORROW'
Не является переменной, а является строковым литералом. При использовании преобразования, например, с помощью функции CAST() в тип даты / времени позволяет получить дату, следующую за текущей. Написание 'TOMORROW' не зависит от регистра, при преобразовании в дату функция игнорирует все пробелы слева и справа от слова.
Примеры:
Пример 7.21. Использование переменной 'TOMORROW'
SELECT CAST('Tomorrow' AS DATE) FROM rdb$database; -- будет возращена завтрашняя дата, например 2014-10-04 SELECT CAST('TOMORROW' AS TIMESTAMP) FROM rdb$database; -- будет возращена завтрашняя дата, например 2014-10-04 00:00:00.0000 -- при использовании короткого "C-Style" литерала -- будет возращена дата на 1 день больше даты подготовки запроса SELECT DATE 'Tomorrow' FROM rdb$database;
Не рекомендуем использовать сокращённые выражения для литерала 'TOMORROW'. Использование таких выражений в компилируемом PSQL приводит к тому, что значение "замораживается" на момент компиляции, и в результате возвращается не актуальное значение. В Firebird 4.0 сокращённые выражения для таких строковых литералов будут запрещены, однако вы по прежнему сможете использовать их при приведении типа оператором CAST. Смотри также Литералы даты и времени.
См. также: CURRENT_DATE, TODAY, YESTERDAY, Преобразование строк в дату и время.
Доступно в: PSQL.
Синтаксис:
UPDATING
Тип возвращаемого результата: BOOLEAN
Контекстная переменная UPDATING доступна только коде табличных триггеров. Используется в триггерах на несколько типов событий и показывает, что триггер сработал при выполнении операции UPDATE.
Примеры:
Пример 7.22. Использование переменной UPDATING
...
IF (INSERTING OR UPDATING) THEN
BEGIN
IF (NEW.SERIAL_NUM IS NULL) THEN
NEW.SERIAL_NUM = GEN_ID (GEN_SERIALS, 1);
END
...
Доступно в: DSQL, PSQL, ESQL.
Синтаксис:
'YERSTERDAY'
Не является переменной, а является строковым литералом. При использовании преобразования, например, с помощью функции CAST() в тип даты / времени позволяет получить дату, предыдущую перед текущей. Написание 'YERSTERDAY' не зависит от регистра, при преобразовании в дату функция игнорирует все пробелы слева и справа от слова.
Примеры:
Пример 7.23. Использование переменной 'YERSTERDAY'
SELECT CAST('Yesterday' AS DATE) FROM rdb$database; -- будет возращена вчерашняя дата, например 2014-10-04 -- использовании короткого "C-Style" литерала -- будет возращена дата 1 день меньше даты подготовки запроса SELECT DATE 'Yesterday' FROM rdb$database; SELECT TIMESTAMP 'YESTERDAY' FROM rdb$database;
Не рекомендуем использовать сокращённые выражения для литерала 'YESTERDAY'. Использование таких выражений в компилируемом PSQL приводит к тому, что значение "замораживается" на момент компиляции, и в результате возвращается не актуальное значение. В Firebird 4.0 сокращённые выражения для таких строковых литералов будут запрещены, однако вы по прежнему сможете использовать их при приведении типа оператором CAST. Смотри также Литералы даты и времени.
См. также: CURRENT_DATE, TODAY, TOMORROW, Преобразование строк в дату и время.
Доступно в: DSQL, PSQL.
Синтаксис:
USER
Тип возвращаемого результата: VARCHAR(31)
Переменная USER содержит имя текущего подключенного пользователя базы данных.
Примеры:
См. также: CURRENT_USER, CURRENT_ROLE.
Если в вашей базе данных имя декларированной внешней функции (DECLARE EXTERNAL FUNCTION) совпадает с именем встроенной, то будет вызываться внешняя функция. Для того чтобы была доступна внутренняя функция, необходимо удалить или изменить имя внешней функции.
Доступно в: DSQL, PSQL.
Синтаксис:
RDB$GET_CONTEXT('<namespace>
', 'varname
')<namespace>
::= SYSTEM | USER_SESSION | USER_TRANSACTION
Параметры функции RDB$GET_CONTEXT
namespace
Пространство имён.
varname
Имя переменной. Зависит от регистра. Максимальная длина 80 символов.
Тип возвращаемого результата: VARCHAR(255)
Функция RDB$GET_CONTEXT возвращает значение контекстной переменной из одного из пространства имён.
В настоящий момент существуют следующие пространства имён:
SYSTEM — предоставляет доступ к системным контекстным переменным. Эти переменные доступны только для чтения;
USER_SESSION — предоставляет доступ к пользовательским контекстным переменным, заданным через функцию RDB$SET_CONTEXT. Переменные существуют в течение подключения;
USER_TRANSACTION — предоставляет доступ к пользовательским контекстным переменным, заданным через функцию RDB$SET_CONTEXT. Переменные существуют в течение транзакции.
Пространства имён USER_SESSION и USER_TRANSACTION — изначально пусты и пользователь сам создаёт переменные и наполняет их при помощи функции RDB$SET_CONTEXT.
Для предотвращения DoS атак, существует ограничение на 1000 переменных в одном "пространстве имён".
Если запрашиваемая функцией переменная существует в указанном пространстве имён, то будет возвращено её значение в виде строки VARCHAR(255). При обращении к несуществующей переменной в пространстве SYSTEM возникает ошибка, если такое происходит с пространствами имён USER_SESSION или USER_TRANSACTION – функция возвращает NULL.
Таблица 7.3. Переменные пространства имён SYSTEM
Переменная | Описание |
---|---|
CLIENT_ADDRESS | Для TCPv 4 – IP адрес, для XNET – локальный ID процесса. Для остальных случаев NULL. |
CLIENT_PID | PID процесса на клиентском компьютере. Добавлено в версии 2.5.3. |
CLIENT_PROCESS | Полный путь к клиентскому приложению, подключившемуся к базе данных. Позволяет не использовать системную таблицу MON$ATTACHMENTS (поле MON$REMOTE_PROCESS). Добавлено в версии 2.5.3. |
CURRENT_ROLE | Глобальная переменная CURRENT_ROLE. |
CURRENT_USER | Глобальная переменная CURRENT_USER. |
DB_NAME | Каноническое имя текущей базы данных. Это либо имя псевдонима (если соединение с помощью имён файлов запрещено DatabaseAccess = NONE) или, в противном случае,полностью расширенное имя файла базы данных. |
ENGINE_VERSION | Версия сервера Firebird. |
ISOLATION_LEVEL | Уровень изоляции текущей транзакции — CURRENT_TRANSACTION. Значения: "READ_COMMITED", "SNAPSHOT" или "CONSISTENCY". |
LOCK_TIMEOUT | Время ожидания транзакцией высвобождения ресурса при блокировке, в секундах. Добавлено в версии 2.5.3. |
NETWORK_PROTOCOL | Протокол, используемый для соединения с базой данных. Возможные значения: "TCPv4", "WNET", "XNET", NULL. |
READ_ONLY | Отображает, является ли транзакция, транзакцией только для чтения. FALSE для R/W транзакций TRUE для ReadOnly. Добавлено в версии 2.5.3. |
SESSION_ID | Глобальная переменная CURRENT_CONNECTION. |
TRANSACTION_ID | Глобальная переменная CURRENT_TRANSACTION. |
Ещё раз обратите внимание на то, что пространства имён и имена переменных регистрочувствительны, должны быть непустыми строками, и заключены в кавычки!
Примеры:
Пример 7.25. Использование функции RDB$GET_CONTEXT
NEW.USER_ADR = RDB$GET_CONTEXT ('SYSTEM', 'CLIENT_ADDRESS');
См. также: RDB$SET_CONTEXT.
Доступно в: DSQL, PSQL.
Синтаксис:
RDB$SET_CONTEXT('<namespace>
', 'varname
', {<value>
| NULL})<namespace>
::= USER_SESSION | USER_TRANSACTION
Параметры функции RDB$SET_CONTEXT
namespace
Пространство имён.
varname
Имя переменной. Зависит от регистра. Максимальная длина 80 символов.
value
Данные любого типа при условии, что их можно привести к типу VARCHAR(255).
Тип возвращаемого результата: INTEGER
Функция RDB$SET_CONTEXT создаёт, устанавливает значение или обнуляет переменную в одном из используемых пользователем пространстве имён: USER_SESSION или USER_TRANSACTION.
Функция возвращает 1, если переменная уже существовала до вызова и 0, если не существовала. Для удаления переменной надо установить её значение в NULL. Если данное пространство имён не существует, то функция вернёт ошибку. Пространство имён и имя переменной зависят от регистра, должны быть не пустыми строками, и заключены в кавычки.
Пространство имён SYSTEM доступно только для чтения;
Максимальное число переменных в рамках одного соединения равно 1000;
Все переменные в пространстве имён USER_TRANSACTION сохраняются при ROLLBACK RETAIN или ROLLBACK TO SAVEPOINT, независимо от того, в какой точке во время выполнения транзакции они были установлены.
Примеры:
Пример 7.26. Использование функции RDB$SET_CONTEXT
SELECT RDB$SET_CONTEXT ('USER_SESSION', 'DEBUGL', 3) FROM RDB$DATABASE; -- в PSQL доступен такой синтаксис RDB$SET_CONTEXT('USER_SESSION', 'RECORDSFOUND', RECCOUNTER); SELECT RDB$SET_CONTEXT ('USER_TRANSACTION', 'SAVEPOINTS', 'YES') FROM RDB$DATABASE;
Пример 7.27. Использование функций для работы с контекстными переменными
SET TERM ^; CREATE PROCEDURE set_context(User_ID VARCHAR(40), Trn_ID INT) AS BEGIN RDB$SET_CONTEXT('USER_TRANSACTION', 'Trn_ID', Trn_ID); RDB$SET_CONTEXT('USER_TRANSACTION', 'User_ID', User_ID); END^ SET TERM ;^ CREATE TABLE journal ( jrn_id INTEGER NOT NULL PRIMARY KEY, jrn_lastuser VARCHAR(40), jrn_lastaddr VARCHAR(255), jrn_lasttran INTEGER ); SET TERM ^; CREATE TRIGGER UI_JOURNAL FOR JOURNAL BEFORE INSERT OR UPDATE AS BEGIN new.jrn_lastuser = RDB$GET_CONTEXT('USER_TRANSACTION', 'User_ID'); new.jrn_lastaddr = RDB$GET_CONTEXT('SYSTEM', 'CLIENT_ADDRESS'); new.jrn_lasttran = RDB$GET_CONTEXT('USER_TRANSACTION', 'Trn_ID'); END^ SET TERM ;^ EXECUTE PROCEDURE set_context('skidder', 1); INSERT INTO journal(jrn_id) VALUES(0); COMMIT;
См. также: RDB$GET_CONTEXT.
Доступно в: DSQL, PSQL.
Синтаксис:
ABS (value
)
Параметры функции ABS
value
Выражение числового типа.
Тип возвращаемого результата: тот же что и входной аргумент.
Функция ABS возвращает абсолютное значение (модуль) аргумента.
Доступно в: DSQL, PSQL.
Синтаксис:
ACOS (value
)
Параметры функции ACOS
value
Выражение числового типа в диапазоне [-1; 1].
Тип возвращаемого результата: DOUBLE PRECISION.
Функция ACOS возвращает арккосинус (в радианах) аргумента.
В случае если аргумент функции вне границы диапазона [-1, 1], то функция вернёт неопределённое значения NaN.
См. также: COS.
Доступно в: DSQL, PSQL.
Синтаксис:
ASIN (value
)
Параметры функции ASIN
value
Выражение числового типа в диапазоне [-1; 1].
Тип возвращаемого результата: DOUBLE PRECISION.
Функция ASIN возвращает арксинус (в радианах) аргумента.
В случае если аргумент функции вне границы диапазона [-1, 1], то функция вернёт неопределённое значения NaN.
См. также: SIN.
Доступно в: DSQL, PSQL.
Синтаксис:
ATAN (value
)
Параметры функции ATAN
value
Выражение числового типа.
Тип возвращаемого результата: DOUBLE PRECISION.
Функция ATAN возвращает арктангенс аргумента.
Функция возвращает угол в радианах в диапазоне [-π/2; π/2].
Доступно в: DSQL, PSQL.
Синтаксис:
ATAN2 (y
,x
)
Параметры функции ATAN2
x
Выражение числового типа.
y
Выражение числового типа.
Тип возвращаемого результата: DOUBLE PRECISION.
Функция ATAN2 возвращает угол как отношение синуса к косинусу, аргументы, у которых задаются этими двумя параметрами, а знаки синуса и косинуса соответствуют знакам параметров. Это позволяет получать результаты по всей окружности, включая углы -π/2 и π/2.
Особенности использования:
Результат — угол в диапазоне [-π, π] радиан;
Если х
отрицательный, то при нулевом значении y
результат равен π, а при значении 0 равен -π;
Если и y и x равны 0, то результат бессмыслен.
Полностью эквивалентное описание этой функции следующее: ATAN2 (y, x) является углом между положительной осью X и линией от начала координат до точки (x, y). Это также делает очевидным, что значение ATAN2 (0, 0) не определено;
Если x
больше, чем 0, ATAN2 (y, x) совпадает с ATAN
(y/x);
Если известны и синус, и косинус угла, то ATAN2 (SIN, COS) возвращает угол.
Доступно в: DSQL, PSQL.
Синтаксис:
CEIL[ING] (number
)
Параметры функции CEIL[ING]
number
Выражение числового типа.
Тип возвращаемого результата: BIGINT или DOUBLE PRECISION.
Функция CEIL возвращает наименьшее целое число, большее или равное аргументу.
Доступно в: DSQL, PSQL.
Синтаксис:
COS (angle
)
Параметры функции COS
angle
Угол, выраженный в радианах.
Тип возвращаемого результата: DOUBLE PRECISION.
Функция COS возвращает косинус угла. Аргумент должен быть задан в радианах.
Любой NOT NULL результат находится в диапазоне [-1, 1].
См. также: ACOS.
Доступно в: DSQL, PSQL.
Синтаксис:
COSH (number
)
Параметры функции COSH
number
Выражение числового типа.
Тип возвращаемого результата: DOUBLE PRECISION.
Функция COSH возвращает гиперболический косинус аргумента.
Любой NOT NULL результат находится в диапазоне [1, +∞].
Доступно в: DSQL, PSQL.
Синтаксис:
COT (angle
)
Параметры функции COT
angle
Угол, выраженный в радианах.
Тип возвращаемого результата: DOUBLE PRECISION.
Функция COT возвращает котангенс угла. Аргумент должен быть задан в радианах.
См. также: TAN.
Доступно в: DSQL, PSQL.
Синтаксис:
EXP (number
)
Параметры функции EXP
number
Выражение числового типа.
Тип возвращаемого результата: DOUBLE PRECISION.
Функция EXP возвращает значение натуральной экспоненты,
См. также: LN.
Доступно в: DSQL, PSQL.
Синтаксис:
FLOOR (number
)
Параметры функции FLOOR
number
Выражение числового типа.
Тип возвращаемого результата: BIGINT или DOUBLE PRECISION.
Функция FLOOR возвращает целое число, меньшее или равное аргументу.
См. также: CEIL, CEILING, TRUNC.
Доступно в: DSQL, PSQL.
Синтаксис:
LN (number
)
Параметры функции LN
number
Выражение числового типа.
Тип возвращаемого результата: DOUBLE PRECISION.
Функция LN возвращает натуральный логарифм аргумента.
В случае если передан отрицательный или нулевой аргумент функция вернёт ошибку.
См. также: EXP.
Доступно в: DSQL, PSQL.
Синтаксис:
LOG (x
,y
)
Параметры функции LOG
x
Основание. Выражение числового типа.
y
Выражение числового типа.
Тип возвращаемого результата: DOUBLE PRECISION.
Функция LOG возвращает логарифм y
(второй аргумент) по
основанию x
(первый аргумент).
Особенности использования:
Если один из аргументов меньше или равен 0, то возникает ошибка;
Если оба аргумента равны 1, то результатом функции будет NaN (Not-a-Number — не число);
Если x
= 1 и y
< 1, то
результатом функции будет -INF (-∞);
Если x
= 1 и y
> 1, то
результатом функции будет +INF (+∞).
Доступно в: DSQL, PSQL.
Синтаксис:
LOG10 (number
)
Параметры функции LOG10
number
Выражение числового типа.
Тип возвращаемого результата: DOUBLE PRECISION.
Функция LOG10 возвращает десятичный логарифм аргумента.
Если входной аргумент отрицательный или равен 0, возникает ошибка.
Доступно в: DSQL, PSQL.
Синтаксис:
MOD (a
,b
)
Параметры функции MOD
a
Выражение числового типа.
b
Выражение числового типа.
Тип возвращаемого результата: INTEGER или BIGINT.
Функция MOD возвращает остаток от целочисленного деления.
Вещественные числа округляются до выполнения деления. Например, результатом 7.5 mod 2.5 будет 2 (8 mod 3), а не 0.
Доступно в: DSQL, PSQL.
Синтаксис:
PI ()
Тип возвращаемого результата: DOUBLE PRECISION.
Функция PI возвращает число π.
Доступно в: DSQL, PSQL.
Синтаксис:
POWER (x
,y
)
Параметры функции POWER
x
Выражение числового типа.
y
Выражение числового типа.
Тип возвращаемого результата: DOUBLE PRECISION.
Функция POWER возвращает результат возведения числа x
в
степень y
.
Если x
меньше нуля, возникает ошибка.
Доступно в: DSQL, PSQL.
Синтаксис:
RAND ()
Тип возвращаемого результата: DOUBLE PRECISION.
Функция RAND возвращает псевдослучайное число в интервале от 0 до 1.
Доступно в: DSQL, PSQL.
Синтаксис:
ROUND (number
[,scale
])
Параметры функции ROUND
number
Выражение числового типа.
scale
Масштаб - целое число, определяющее число десятичных разрядов, к которым должен быть проведено округление, т.е.
2 для округления к самому близкому кратному 0.01 числу 1 для округления к самому близкому кратному 0.1 числу 0 для округления к самому близкому целому числу -1 для округления к самому близкому кратному 10 числу -2 для округления к самому близкому кратному 100 числу
По умолчанию 0.
Тип возвращаемого результата: INTEGER, масштабируемый BIGINT, DOUBLE PRECISION.
Функция ROUND округляет число до ближайшего целого числа. Если дробная часть равна
0.5, то округление до ближайшего большего целого числа для положительных чисел и до
ближайшего меньшего для отрицательных чисел. С дополнительным опциональным параметром
scale
число может быть округлено до одной из степеней числа
10 (десятки, сотни, десятые части, сотые части и т.д.) вместо просто целого числа.
Если используется параметр scale
, то результат имеет
такой же масштаб, как и первый параметр number
.
Примеры:
Пример 7.28. Использование функции ROUND
ROUND(123.654, 1) -- Результат: 123.700 (а не 123.7) ROUND(8341.7, -3) -- Результат: 8000.0 (а не 8000) ROUND(45.1212, 0) -- Результат: 45.0000 (а не 45) ROUND(45.1212) -- Результат: 45
См. также: TRUNC.
Доступно в: DSQL, PSQL.
Синтаксис:
SIGN (number
)
Параметры функции SIGN
number
Выражение числового типа.
Тип возвращаемого результата: SMALLINT.
Функция SIGN возвращает знак входного параметра.
Таблица 7.4. Таблица результатов функции SIGN
Результат | Значение |
---|---|
-1 | число меньше нуля |
0 | число равно нулю |
1 | число больше нуля |
Доступно в: DSQL, PSQL.
Синтаксис:
SIN (angle
)
Параметры функции SIN
angle
Угол, выраженный в радианах.
Тип возвращаемого результата: DOUBLE PRECISION.
Функция SIN возвращает синус угла. Аргумент должен быть задан в радианах.
Любой NOT NULL результат находится в диапазоне [-1, 1].
См. также: ASIN.
Доступно в: DSQL, PSQL.
Синтаксис:
SINH (number
)
Параметры функции SINH
number
Выражение числового типа.
Тип возвращаемого результата: DOUBLE PRECISION.
Функция SINH возвращает гиперболический синус аргумента.
Доступно в: DSQL, PSQL.
Синтаксис:
SQRT (number
)
Параметры функции SQRT
number
Выражение числового типа.
Тип возвращаемого результата: DOUBLE PRECISION.
Функция SQRT возвращает квадратный корень аргумента.
Доступно в: DSQL, PSQL.
Синтаксис:
TAN (angle
)
Параметры функции TAN
angle
Угол, выраженный в радианах.
Тип возвращаемого результата: DOUBLE PRECISION.
Функция TAN возвращает тангенс угла. Аргумент должен быть задан в радианах.
Доступно в: DSQL, PSQL.
Синтаксис:
TANH (number
)
Параметры функции TANH
number
Выражение числового типа.
Тип возвращаемого результата: DOUBLE PRECISION.
Функция TANH возвращает гиперболический тангенс аргумента.
Любой NOT NULL результат находится в диапазоне [-1, 1].
Доступно в: DSQL, PSQL.
Синтаксис:
TRUNC (number
[,scale
])
Параметры функции TRUNC
number
Выражение числового типа.
scale
Масштаб - целое число, определяющее число десятичных разрядов, к которым должен быть проведено усечение, т.е.
2 для усечения к самому близкому кратному 0.01 числу 1 для усечения к самому близкому кратному 0.1 числу 0 для усечения к самому близкому целому числу -1 для усечения к самому близкому кратному 10 числу -2 для усечения к самому близкому кратному 100 числу
По умолчанию 0.
Тип возвращаемого результата: INTEGER, масштабируемый BIGINT, DOUBLE PRECISION.
Функция TRUNC усекает число до ближайшего целого числа. С дополнительным опциональным
параметром scale
число может быть усечено до одной из степеней
числа 10 (десятки, сотни, десятые части, сотые части и т.д.) вместо просто целого
числа.
Если используется параметр scale
, то результат имеет
такой же масштаб, как и первый параметр number
.
Функция всегда увеличивает отрицательные числа, поскольку она обрезает дробную часть.
Примеры:
Пример 7.29. Использование функции TRUNC
TRUNC(789.2225, 2) -- Результат: 789.2200 (а не 789.22) TRUNC(345.4, -2) -- Результат: 300.0 (а не 300) TRUNC(-163.41, 0) -- Результат: -163.00 (а не -163) TRUNC(-163.41) -- Результат: -163
См. также: ROUND, CEIL, CEILING, FLOOR.
Доступно в: DSQL, PSQL.
Синтаксис:
ASCII_CHAR (code
)
Параметры функции ASCII_CHAR
code
Целое число в диапазоне от 0 до 255.
Тип возвращаемого результата: [VAR]CHAR(1) CHARSET NONE.
Функция ASCII_CHAR возвращает ASCII символ соответствующий номеру, переданному в качестве аргумента.
См. также: ASCII_VAL.
Доступно в: DSQL, PSQL.
Синтаксис:
ASCII_VAL (ch
)
Параметры функции ASCII_VAL
ch
Строка типа данных [VAR]CHAR или текстовый BLOB максимального размера 32767 байт.
Тип возвращаемого результата: SMALLINT.
Функция ASCII_VAL возвращает ASCII код символа, переданного в качестве аргумента.
Особенности использования:
Если строка содержит более одного символа, то возвращается код первого символа строки;
Если строка пустая, возвращается ноль;
Если аргумент NULL, то возвращаемое значение также NULL.
См. также: ASCII_CHAR.
Доступно в: DSQL, PSQL.
Синтаксис:
BIT_LENGTH (str
)
Параметры функции BIT_LENGTH
str
Выражение строкового типа.
Тип возвращаемого результата: INTEGER.
Функция BIT_LENGTH возвращает длину входной строки в битах. Для многобайтных наборов символов результат может быть в 8 раз больше, чем количество символов в "формальном" числе байт на символ, записанном в RDB$CHARACTER_SETS.
С параметрами типа CHAR эта функция берет во внимание всю формальную строковую длину (например, объявленная длина поля или переменной). Если вы хотите получить "логическую" длину в битах, не считая пробелов, то перед передачей аргумента в BIT_LENGTH надо выполнить над ним операцию RIGHT TRIM.
Примеры:
Пример 7.30. Использование функции BIT_LENGTH
SELECT BIT_LENGTH ('Hello!') FROM RDB$DATABASE -- возвращает 48 SELECT BIT_LENGTH (_ISO8859_1 'Grüß Di!') FROM RDB$DATABASE -- возвращает 64: каждый, и ü, и ß занимают один байт в ISO8859_1 SELECT BIT_LENGTH ( CAST (_ISO8859_1 'Grüß di!' AS VARCHAR (24) CHARACTER SET UTF8)) FROM RDB$DATABASE -- возвращает 80: каждый, и ü, и ß занимают по два байта в UTF8 SELECT BIT_LENGTH ( CAST (_ISO8859_1 'Grüß di!' AS CHAR (24) CHARACTER SET UTF8)) FROM RDB$DATABASE -- возвращает 208: размер всех 24 позиций CHAR и два из них 16-битные
См. также: CHAR_LENGTH, OCTET_LENGTH.
Доступно в: DSQL, PSQL.
Синтаксис:
CHAR_LENGTH (str
) CHARACTER_LENGTH (str
)
Параметры функции CHAR_LENGTH
str
Выражение строкового типа.
Тип возвращаемого результата: INTEGER.
Функция CHAR_LENGTH возвращает длину (в символах) строки, переданной в качестве аргумента.
С параметрами типа CHAR эта функция берет во внимание всю формальную строковую длину (например, объявленная длина поля или переменной). Если вы хотите получить "логическую" длину без учёта пробелов, то перед передачей аргумента в CHAR[ACTER]_LENGTH надо выполнить над ним операцию RIGHT TRIM.
См. также: BIT_LENGTH, OCTET_LENGTH.
Доступно в: DSQL, PSQL.
Синтаксис:
HASH (str
)
Параметры функции HASH
str
Выражение строкового типа.
Тип возвращаемого результата: BIGINT.
Функция HASH возвращает хэш-значение входной строки. Эта функция полностью поддерживает текстовые BLOB любой длины и с любым набором символов.
Доступно в: DSQL, PSQL.
Синтаксис:
LEFT (str
,num
)
Параметры функции LEFT
str
Выражение строкового типа.
num
Целое число. Определяет количество возвращаемых символов.
Тип возвращаемого результата: VARCHAR(N) или BLOB.
Функция LEFT возвращает левую часть строки, количество возвращаемых символов определяется вторым параметром.
Особенности использования:
Функция поддерживает текстовые блоки любой длины и с любыми наборами символов;
Если строковый аргумент BLOB, результатом будет BLOB, в противном случае результатом будет VARCHAR(N), при этом N – будет равно длине строкового параметра;
Если числовой параметр превысит длину текста, результатом будет исходный текст.
При использовании BLOB в параметрах функции может потребоваться загрузить объект полностью в память. При больших объёмах BLOB могут наблюдаться потери производительности.
Примеры:
Доступно в: DSQL, PSQL, ESQL.
Синтаксис:
LOWER (str
)
Параметры функции LOWER
str
Выражение строкового типа.
Тип возвращаемого результата: VARCHAR(N) или BLOB.
Функция LOWER возвращает входную строку в нижнем регистре. Точный результат зависит от набора символов входной строки. Например, для наборов символов NONE и ASCII только ASCII символы переводятся в нижний регистр; для OCTETS – вся входная строка возвращается без изменений.
Примеры:
Пример 7.32. Использование функции LOWER
/* Результат: 'debacle', в соответствии с французскими * правилами приведения в нижний регистр */ SELECT LOWER(_ISO8859_1 'Débâcle' COLLATE FR_FR) FROM RDB$DATABASE
См. также: UPPER.
Доступно в: DSQL, PSQL.
Синтаксис:
LPAD (str
,endlen
[,padstr
])
Параметры функции LPAD
str
Выражение строкового типа.
endlen
Длина выходной строки.
padstr
Строка, которой дополняется исходная строка до указанной длины. По умолчанию является пробелом (' ').
Тип возвращаемого результата: VARCHAR(endlen
) или BLOB.
Функция LPAD дополняет слева входную строку пробелами или определённой пользователем строкой до заданной длины.
Особенности использования:
Функция поддерживает текстовые блоки любой длины и с любыми наборами символов;
Если входная строка имеет тип BLOB, то результат также будет BLOB, в противном
случае результат будет VARCHAR(endlen
).
Если аргумент padstr
задан, но равен пустой строке
(''), то дополнения строки не происходит! В случае если
endlen
меньше длины входной строки, то в результате
происходит её усечение до длины endlen
, даже если
параметр padstr
равен пустой строке.
При использовании BLOB в параметрах функции может потребоваться загрузить объект полностью в память. При больших объёмах BLOB могут наблюдаться потери производительности.
Примеры:
Пример 7.33. Использование функции LPAD
LPAD ('Hello', 12) -- возвращает ' Hello' LPAD ('Hello', 12, '-') -- возвращает '-------Hello' LPAD ('Hello', 12, '') -- возвращает 'Hello' LPAD ('Hello', 12, 'abc') -- возвращает 'abcabcaHello' LPAD ('Hello', 12, 'abcdefghij') -- возвращает 'abcdefgHello' LPAD ('Hello', 2) -- возвращает 'He' LPAD ('Hello', 2, '-') -- возвращает 'He' LPAD ('Hello', 2, '') -- возвращает 'He'
См. также: RPAD.
Доступно в: DSQL, PSQL.
Синтаксис:
OCTET_LENGTH (str
)
Параметры функции OCTET_LENGTH
str
Выражение строкового типа.
Тип возвращаемого результата: INTEGER.
Функция OCTET_LENGTH возвращает количество байт занимаемое строкой.
При работе с параметрами типа CHAR функция возвращает значение всей формальной строковой длины. Для того чтобы узнать "логическую" длину строки в байтах, то перед передачей аргумента функции следует применить RIGHT TRIM.
Следует помнить, что не во всех наборах символов количество байт занимаемых строкой равно количеству символов.
Примеры:
Пример 7.34. Использование функции OCTET_LENGTH
SELECT OCTET_LENGTH('Hello!') FROM rdb$database -- возвратит 6 SELECT OCTET_LENGTH(_iso8859_1 'Grüß di!') FROM rdb$database -- возвратит 8: ü и ß занимают не более 1 байта в ISO8859_1 SELECT OCTET_LENGTH(CAST(_iso8859_1 'Grüß di!' AS VARCHAR(24) CHARACTER SET utf8)) FROM rdb$database -- возвратит 10: ü и ß занимают 2 байта в UTF8 SELECT OCTET_LENGTH(CAST(_iso8859_1 'Grüß di!' AS CHAR(24) CHARACTER SET utf8)) FROM rdb$database -- возвратит 26: всего 24 CHAR позиции, и две из них занимают 2 байта
См. также: BIT_LENGTH, CHAR_LENGTH.
Доступно в: DSQL, PSQL.
Синтаксис:
OVERLAY (string
PLACINGreplacement
FROMpos
[FORlength
])
Параметры функции OVERLAY
string
Строка, в которой происходит замена.
replacement
Строка, которой заменяется.
pos
Позиция, с которой происходит замена.
length
Количество символов, которые будут удалены из исходной строки.
Тип возвращаемого результата: VARCHAR(N) или BLOB.
Функция OVERLAY предназначена для замены части строки другой строкой.
По умолчанию число удаляемых из строки символов равняется длине заменяемой строки. Дополнительный четвёртый параметр позволяет пользователю задать своё число символов, которые будут удалены.
Особенности использования:
Функция полностью поддерживает тестовые BLOB с любым набором символов и любой длины;
Если входная строка имеет тип BLOB, то и результат будет иметь тип BLOB. В
противном случае тип результата будет VARCHAR(n), где n является суммой длин
параметров string
и
replacement
;
Как и во всех строковых функциях SQL параметр pos
является определяющим;
Если pos
больше длины строки, то
replacement
помещается сразу после окончания
строки;
Если число символов от pos
до конца строки меньше,
чем длина replacement
(или, чем параметр
length
, если он задан), то строка усекается до значения
pos и replacement
помещается после него;
При нулевом параметре length
(FOR 0)
replacement
просто вставляется в строку, начиная с
позиции pos
;
Если любой из параметров имеет значение NULL, то и результат будет NULL;
Если параметры pos
и
length
не являются целым числом, то используется
банковское округление (до чётного): 0.5 становится 0, 1.5 становится 2, 2.5
становится 2, 3.5 становится 4 и т.д.
При использовании BLOB функции может потребоваться загрузить весь объект в память. При больших размерах BLOB это может повлиять на производительность.
Примеры:
Пример 7.35. Использование функции OVERLAY
OVERLAY ('Goodbye' PLACING 'Hello' FROM 2) -- Результат: 'Ghelloe' OVERLAY ('Goodbye' PLACING 'Hello' FROM 5) -- Результат: 'GoodHello' OVERLAY ('Goodbye' PLACING 'Hello' FROM 8) -- Результат: 'GoodbyeHello' OVERLAY ('Goodbye' PLACING 'Hello' FROM 20) -- Результат: 'GoodbyeHello' OVERLAY ('Goodbye' PLACING 'Hello' FROM 2 FOR 0) -– Результат: 'GHellooodbye' OVERLAY ('Goodbye' PLACING 'Hello' FROM 2 FOR 3) -- Результат: 'GHellobye' OVERLAY ('Goodbye' PLACING 'Hello' FROM 2 FOR 6) -- Результат: 'GHello' OVERLAY ('Goodbye' PLACING 'Hello' FROM 2 FOR 9) -- Результат: 'Ghello' OVERLAY ('Goodbye' PLACING '' FROM 4) -- Результат: 'Goodbye' OVERLAY ('Goodbye' PLACING '' FROM 4 FOR 3) -- Результат: 'Gooe' OVERLAY ('Goodbye' PLACING '' FROM 4 FOR 20) -- Результат: 'Goo' OVERLAY ('' PLACING 'Hello' FROM 4) -- Результат: 'Hello' OVERLAY ('' PLACING 'Hello' FROM 4 FOR 0) -- Результат: 'Hello' OVERLAY ('' PLACING 'Hello' FROM 4 FOR 20) -- Результат: 'Hello'
Доступно в: DSQL, PSQL.
Синтаксис:
POSITION (<args>
)<args>
::=substr
INstring
|substr
,string
[,startpos
]
Параметры функции POSITION
substr
Подстрока, позиция которой ищется.
string
Строка, в которой ищется позиция.
startpos
Позиция, с которой начинается поиск подстроки.
Тип возвращаемого результата: INTEGER.
Функция POSITION возвращает позицию первого вхождения подстроки в строку. Отсчёт начинается с 1. Третий аргумент (опциональный) задаёт позицию в строке, с которой начинается поиск подстроки, тем самым игнорирую любые вхождения подстроки в строку до этой позиции. Если совпадение не найдено, функция возвращает 0.
Особенности использования:
Опциональный третий параметр поддерживается только вторым вариантом синтаксиса (синтаксис с запятой);
Пустую строку, функция считает подстрокой любой строки. Поэтому при входном
параметре substr
, равном '' (пустая строка), и при
параметре string
, отличном от NULL, результатом будет:
1, если параметр startpos
не задан;
1, если параметр startpos
не задан;
startpos
, если
startpos
не превышает длину параметра
string
.
Примеры:
Пример 7.36. Использование функции POSITION
POSITION ('be' IN 'To be or not to be') -- Результат: 4 POSITION ('be', 'To be or not to be') -- Результат: 4 POSITION ('be', 'To be or not to be', 4) -- Результат: 4 POSITION ('be', 'To be or not to be', 8) -- Результат: 17 POSITION ('be', 'To be or not to be', 18) -- Результат: 0 POSITION ('be' in 'Alas, poor Yorick!') -- Результат: 0
См. также: SUBSTRING.
Доступно в: DSQL, PSQL.
Синтаксис:
REPLACE (str
,find
,repl
)
Параметры функции REPLACE
str
Строка, в которой делается замена.
find
Строка, которая ищется.
repl
Строка, на которую происходит замена.
Тип возвращаемого результата: VARCHAR(N) или BLOB.
Функция REPLACE заменяет в строке все вхождения одной строки на другую строку.
Особенности использования:
Функция поддерживает текстовые блоки любой длины и с любыми наборами символов;
Если один из аргументов имеет тип BLOB, то результат будет иметь тип BLOB. В
противном случае результат будет иметь тип VARCHAR(N), где N рассчитывается из длин
str
, find
и
repl
таким образом, что даже максимальное количество
замен не будет вызывать переполнения поля.
Если параметр find
является пустой строкой, то
возвращается str
без изменений;
Если параметр repl
является пустой строкой, то все
вхождения find
удаляются из строки
str
;
Если любой из аргументов равен NULL, то результатом всегда будет NULL, даже если не было произведено ни одной замены.
При использовании BLOB в параметрах функции может потребоваться загрузить объект полностью в память. При больших объёмах BLOB могут наблюдаться потери производительности.
Примеры:
Пример 7.37. Использование функции REPLACE
REPLACE ('Billy Wilder', 'il', 'oog') -- возвращает 'Boogly Woogder' REPLACE ('Billy Wilder', 'il', '') -- возвращает 'Bly Wder' REPLACE ('Billy Wilder', null, 'oog') -- возвращает NULL REPLACE ('Billy Wilder', 'il', null) -- возвращает NULL REPLACE ('Billy Wilder', 'xyz', null) -- возвращает NULL (!) REPLACE ('Billy Wilder', 'xyz', 'abc') -- возвращает 'Billy Wilder' REPLACE ('Billy Wilder', '', 'abc') -- возвращает 'Billy Wilder'
См. также: OVERLAY.
Доступно в: DSQL, PSQL.
Синтаксис:
REVERSE (str
)
Параметры функции REVERSE
str
Выражение строкового типа.
Тип возвращаемого результата: VARCHAR(N).
Функция REVERSE возвратит строку перевёрнутую "задом наперёд".
Примеры:
Пример 7.38. Использование функции REVERSE
REVERSE ('spoonful') -- возвращает 'lufnoops' REVERSE ('Was it a cat I saw?') -- возвращает '?was I tac a ti saW'
Данная функция очень удобна, если вам предстоит работать (сортировать или группировать информацию) которая находится в окончаниях строк. Пример такой информации – доменные имена или имена адресов электронной почты.
CREATE INDEX ix_people_email ON people
COMPUTED BY (reverse(email));
SELECT * FROM people
WHERE REVERSE(email) STARTING WITH reverse('.br');
Доступно в: DSQL, PSQL.
Синтаксис:
RIGHT (str
,num
)
Параметры функции RIGHT
str
Выражение строкового типа.
num
Целое число. Определяет количество возвращаемых символов.
Тип возвращаемого результата: VARCHAR(N) или BLOB.
Функция RIGHT возвращает конечную (правую) часть входной строки. Длина возвращаемой подстроки определяется вторым параметром.
Особенности использования:
Функция поддерживает текстовые блоки любой длины и с любыми наборами символов;
Если строковый аргумент BLOB, результатом будет BLOB, в противном случае результатом будет VARCHAR(N), при этом N – будет равно длине строкового параметра;
Если числовой параметр превысит длину текста, результатом будет исходный текст.
При использовании BLOB в параметрах функции может потребоваться загрузить объект полностью в память. При больших объёмах BLOB могут наблюдаться потери производительности.
Примеры:
Доступно в: DSQL, PSQL.
Синтаксис:
RPAD (str
,endlen
[,padstr
])
Параметры функции RPAD
str
Выражение строкового типа.
endlen
Длина выходной строки.
padstr
Строка, которой дополняется исходная строка до указанной длины. По умолчанию является пробелом (' ').
Тип возвращаемого результата: VARCHAR(endlen
) или BLOB.
Функция RPAD дополняет справа входную строку пробелами или определённой пользователем строкой до заданной длины.
Особенности использования:
Функция поддерживает текстовые блоки любой длины и с любыми наборами символов;
Если входная строка имеет тип BLOB, то результат также будет BLOB, в противном
случае результат будет VARCHAR(endlen
).
Если аргумент padstr
задан, но равен пустой строке
(''), то дополнения строки не происходит! В случае если
endlen
меньше длины входной строки, то в результате
происходит её усечение до длины endlen
, даже если
параметр padstr
равен пустой строке.
При использовании BLOB в параметрах функции может потребоваться загрузить объект полностью в память. При больших объёмах BLOB могут наблюдаться потери производительности.
Примеры:
Пример 7.40. Использование функции RPAD
RPAD ('Hello', 12) -- возвращает 'Hello ' RPAD ('Hello', 12, '-') -- возвращает 'Hello-------' RPAD ('Hello', 12, '') -- возвращает 'Hello' RPAD ('Hello', 12, 'abc') -- возвращает 'Helloabcabca' RPAD ('Hello', 12, 'abcdefghij') -- возвращает 'Helloabcdefg' RPAD ('Hello', 2) -- возвращает 'He' RPAD ('Hello', 2, '-') -- возвращает 'He' RPAD ('Hello', 2, '') -- возвращает 'He'
См. также: LPAD.
Доступно в: DSQL, PSQL.
Синтаксис:
SUBSTRING (str
FROMstartpos
[FORlength
])
Параметры функции SUBSTRING
str
Выражение строкового типа.
startpos
Позиция, с которой начинается извлечение подстроки. Целочисленное выражение.
length
Длина возвращаемой подстроки. Целочисленное выражение.
Тип возвращаемого результата: VARCHAR(N) или BLOB.
Функция SUBSTRING возвращает подстроку строки str
, начиная
с позиции startpos
(позиция начинается с 1) до конца строки или
указанной длины. Без предложения FOR возвращаются все оставшиеся символы в строке. С
предложением FOR возвращается length
символов или остаток
строки, в зависимости от того что короче.
Функция полностью поддерживает двоичные и текстовые BLOB любой длины и с любым набором
символов. Если параметр str
имеет тип BLOB, то и результат
будет иметь тип BLOB. Для любых других типов результатом будет тип VARCHAR(n). Для
входного параметра str
, не являющегося BLOB, длина результата
функции всегда будет равна длине строки str
, независимо от
значений параметров startpos
и
length
.
Если любой из входных параметров имеет значение NULL, то и результат тоже будет иметь значение NULL.
При использовании BLOB в параметрах функции может потребоваться загрузить объект в память полностью. При больших объёмах BLOB могут наблюдаться потери производительности.
Примеры:
Пример 7.41. Использование функции SUBSTRING
SUBSTRING('Привет!' FROM 4 FOR 3) -- вернёт подстроку 'вет'
См. также: POSITION, LEFT, RIGHT, CHAR_LENGTH.
Доступно в: DSQL, PSQL.
Синтаксис:
TRIM ([<adjust>
]str
)<adjust>
::= {[<where>
] [what
]} FROM<where>
::= BOTH | LEADING | TRAILING
Параметры функции TRIM
str
Выражение строкового типа.
where
Из какого места необходимо удалить подстроку. По умолчанию BOTH.
what
Подстрока, которую надо удалить (неоднократно, если таких вхождений несколько)
из входной строки str
в её начале и/или конце. По
умолчанию является пробелом (' ').
Тип возвращаемого результата: VARCHAR(N) или BLOB.
Функция TRIM удаляет начальные и /или концевые пробелы (или текст согласно настройкам) из входной строки.
Таблица 7.5. Спецификация опций функции TRIM
Опция | Описание |
---|---|
BOTH | с обеих сторон строки (по умолчанию) |
LEADING | с начала строки |
TRAILING | с конца строки |
Особенности использования:
Если входной параметр str
имеет тип BLOB, то и
результат будет иметь тип BLOB. В противном случае результат будет иметь тип
VARCHAR(n), где n является длиной параметра str
;
Подстрока для удаления, если она, конечно, задана, не должна иметь длину больше,
чем 32767 байта. Однако при повторениях подстроки в начале и/или конце входного
параметра str
общее число удаляемых байтов может быть
гораздо больше.
При использовании BLOB в параметрах функции может потребоваться загрузить объект в память полностью. При больших объёмах BLOB могут наблюдаться потери производительности.
Примеры:
Пример 7.42. Использование функции TRIM
SELECT TRIM (' Waste no space ') FROM RDB$DATABASE -- Результат: 'Waste no space' SELECT TRIM (LEADING FROM ' Waste no space ') FROM RDB$DATABASE -- Результат: 'Waste no space ' SELECT TRIM (LEADING '.' FROM ' Waste no space ') FROM RDB$DATABASE -- Результат: ' Waste no space ' SELECT TRIM (TRAILING '!' FROM 'Help!!!!') FROM RDB$DATABASE -- Результат: 'Help' SELECT TRIM ('la' FROM 'lalala I love you Ella') FROM RDB$DATABASE -- Результат: ' I love you El'
Доступно в: DSQL, PSQL, ESQL.
Синтаксис:
UPPER (str
)
Параметры функции UPPER
str
Выражение строкового типа.
Тип возвращаемого результата: VARCHAR(N) или BLOB.
Функция UPPER возвращает входную строку в верхнем регистре. Точный результат зависит от набора символов входной строки. Например, для наборов символов NONE и ASCII только ASCII символы переводятся в верхний регистр; для OCTETS — вся входная строка возвращается без изменений.
Примеры:
Пример 7.43. Использование функции UPPER
/* Результат: 'DEBACLE', в соответствии с французскими * правилами приведения в верхний регистр */ SELECT UPPER(_ISO8859_1 'Débâcle' COLLATE FR_FR) FROM RDB$DATABASE
См. также: LOWER.
Доступно в: DSQL, PSQL.
Синтаксис:
DATEADD (<args>
)<args>
::=amount
<unit>
TOdatetime
|<unit>
,amount
,datetime
<unit>
::= YEAR | MONTH | WEEK | DAY | WEEKDAY | YEARDAY | HOUR | MINUTE | SECOND | MILLISECOND
Параметры функции DATEADD
amount
Целое выражение типа SMALLINT или INTEGER (отрицательное вычитается).
unit
Составляющая даты/времени.
datetime
Выражение типа DATE, TIME или TIMESTAMP.
Тип возвращаемого результата: определяется третьим аргументом функции.
Функция DATEADD позволяет добавить заданное число лет, месяцев, недель, часов, минут, секунд, миллисекунд к заданному значению даты/времени.
С аргументом типа TIMESTAMP и DATE можно использовать любую составляющую
даты/времени (<unit>
);
Для типа данных TIME разрешается использовать только HOUR, MINUTE, SECOND и MILLISECOND.
Примеры:
Пример 7.44. Использование функции DATEADD
DATEADD (28 DAY TO CURRENT_DATE) DATEADD (-6 HOUR TO CURRENT_TIME) DATEADD (MONTH, 9, DATEOFCONCEPTION) DATEADD (-38 WEEK TO DATEOFBIRTH) DATEADD (MINUTE, 90, TIME 'NOW') DATEADD (? YEAR TO DATE '11-SEP-1973')
См. также: DATEDIFF, Операции, использующие значения даты и времени.
Доступно в: DSQL, PSQL.
Синтаксис:
DATEDIFF (<args>
)<args>
::=<unit>
FROMmoment_1
TOmoment_2
|<unit>
,moment_1
,moment_2
<unit>
::= YEAR | MONTH | WEEK | DAY | WEEKDAY | YEARDAY | HOUR | MINUTE | SECOND | MILLISECOND
Параметры функции DATEDIFF
unit
Составляющая даты/времени.
monent_1
Выражение типа DATE, TIME или TIMESTAMP.
monent_2
Выражение типа DATE, TIME или TIMESTAMP.
Тип возвращаемого результата: BIGINT.
Функция DATEDIFF возвращает количество лет, месяцев, недель, дней, часов, минут, секунд или миллисекунд между двумя значениями даты/времени.
Особенности использования:
Параметры DATE и TIMESTAMP могут использоваться совместно. Совместное использование типа TIME с типами DATE и TIMESTAMP не разрешается;
С аргументом типа TIMESTAMP и DATE можно использовать любую составляющую
даты/времени (<unit>
);
Для типа данных TIME разрешается использовать только HOUR, MINUTE, SECOND и MILLISECOND.
Функция DATEDIFF не проверяет разницу в более мелких составляющих
даты/времени, чем задана в первом аргументе
(<unit>
). В результате получаем:
- DATEDIFF (YEAR, DATE '1-JAN-2009', DATE '31-DEC-2009') = 0, но - DATEDIFF (YEAR, DATE '31-DEC-2009', DATE '1-JAN-2010') = 1
Однако для более мелких составляющих даты/времени имеем:
- DATEDIFF (DAY, DATE '26-JUN-1908', DATE '11-SEP-1973') = 23818 - DATEDIFF (DAY, DATE '30-NOV-1971', DATE '8-JAN-1972') = 39
Отрицательное значение функции говорит о том, что дата/время в
moment_2
меньше, чем в
moment_1
.
Примеры:
Пример 7.45. Использование функции DATEDIFF
DATEDIFF (HOUR FROM CURRENT_TIMESTAMP TO TIMESTAMP '12-JUN-2059 06:00') DATEDIFF (MINUTE FROM TIME '0:00' TO CURRENT_TIME) DATEDIFF (MONTH, CURRENT_DATE, DATE '1-1-1900') DATEDIFF (DAY FROM CURRENT_DATE TO CAST (? AS DATE))
См. также: DATEADD, Операции, использующие значения даты и времени.
Доступно в: DSQL, PSQL, ESQL.
Синтаксис:
EXTRACT (<part>
FROMdatetime
)<part>
::= YEAR | MONTH | WEEK | DAY | WEEKDAY | YEARDAY | HOUR | MINUTE | SECOND | MILLISECOND
Параметры функции EXTRACT
part
Составляющая даты/времени.
datetime
Выражение типа DATE, TIME или TIMESTAMP.
Тип возвращаемого результата: SMALLINT или NUNERIC.
Функция EXTRACT извлекает составляющие даты и времени из типов данных DATE, TIME и TIMESTAMP.
Таблица 7.6. Типы и диапазоны результатов функции EXTRACT
Составляющая даты/времени | Тип | Диапазон | Комментарий |
---|---|---|---|
YEAR | SMALLINT | 1–9999 | |
MONTH | SMALLINT | 1–12 | |
WEEK | SMALLINT | 1–53 | |
DAY | SMALLINT | 1–31 | |
WEEKDAY | SMALLINT | 0–6 | 0 = Воскресенье |
YEARDAY | SMALLINT | 0–365 | 0 = 1 января |
HOUR | SMALLINT | 0–23 | |
MINUTE | SMALLINT | 0–59 | |
SECOND | NUMERIC(9,4) | 0.0000–59.9999 | Включает в себя миллисекунды |
MILLISECOND | NUMERIC(9,1) | 0.0–999.9 |
Если составляющая даты/времени не присутствует в аргументе дата/время, например, SECOND в аргументе с типом DATE или YEAR в TIME, то функция вызовет ошибку.
Из аргумента с типом данных DATE или TIMESTAMP можно извлекать номер недели. В соответствии со стандартом ISO-8601 неделя начинается с понедельника и всегда включает в себя 7 дней. Первой неделей года является первая неделя, у которой в ней больше дней в новом году (по крайней мере, 4): дни 1-3 могут принадлежать предыдущей неделе (52 или 53) прошлого года. По аналогии дни 1-3 текущего года могут принадлежать 1 неделе следующего года.
Примеры:
Пример 7.46. Использование функции EXTRACT
/* получить по дате номер квартала */ SELECT (EXTRACT(MONTH FROM CURRENT_TIMESTAMP)-1)/3+1 FROM RDB$DATABASE
См. также: Типы данных для работы с датой и временем.
Доступно в: DSQL, PSQL, ESQL.
Синтаксис:
CAST(value
| NULL AS<type>
)<type>
::=<datatype>
| [TYPE OF]domain
| TYPE OF COLUMNrelname
.colname
<datatype>
::= {SMALLINT | INTEGER | BIGINT} | {FLOAT | DOUBLE PRECISION} | {DATE | TIME | TIMESTAMP} | {DECIMAL | NUMERIC} [(precision
[,scale
])] | {CHAR | CHARACTER | CHARACTER VARYING | VARCHAR} [(size
)] [CHARACTER SETcharset
] | {NCHAR | NATIONAL CHARACTER | NATIONAL CHAR} [VARYING] [(size
)] | BLOB [SUB_TYPE {subtype_num
|subtype_name
}] [SEGMENT SIZEseglen
] [CHARACTER SETcharset
] | BLOB [(seglen
[,subtype_num
])]
Сокращённый синтаксис:
<datatype>
'date/timestring
'<datatype>
::= DATE | TIME | TIMESTAMP
Параметры функции CAST
value
SQL выражение.
datatype
Тип данных SQL.
domain
Домен.
relname
Имя таблицы или представления.
colname
Имя столбца таблицы или представления.
precision
Точность. От 1 до 18.
scale
Масштаб. От 0 до 18, должно быть меньше или равно
precision
.
size
Максимальный размер строки в символах.
charset
Набор символов.
subtype_num
Номер подтипа BLOB.
subtype_name
Мнемоника подтипа BLOB.
seqlen
Размер сегмента, не может превышать 65535
Тип возвращаемого результата: <type>
.
Функция CAST служит для явного преобразования данных из одного типа данных в другой тип данных или домен. Если это невозможно будет выдана ошибка.
Сокращённый синтаксис поддерживается только для литералов даты и времени.
Сокращенный синтаксис вычисляется сразу во время синтаксического анализа, в результате чего значение сохраняется до тех пор пока для оператора не сделано unprepare. Для литералов даты и времени таких как '12-OCT-2012' это не имеет никакого значения. Но для псевдо-переменных 'NOW', 'YESTERDAY', 'TODAY' и 'TOMORROW' вы можете получить не то, что хотите. Если вам нужно значение, которое будет вычисляться при каждом вызове, используйте CAST().
Таблица 7.7. Допустимые преобразования для функции CAST
Из типа | В тип | ||||||||
---|---|---|---|---|---|---|---|---|---|
|
|
||||||||
|
|
||||||||
|
|
||||||||
|
|
Имейте ввиду, что иногда информация может быть потерянна, например, когда вы преобразуете тип TIMESTAMP к DATE. Кроме того, тот факт, что типы совместимы для функции CAST, ещё не гарантирует, что преобразование будет успешным. "CAST (123456789 AS SMALLINT)" безусловно приведёт к ошибке, так же как и "CAST('Judgement Day' as DATE)".
Примеры:
Полный синтаксис:
select cast ('12' || '-June-' || '1959' as date) from rdb$database
Сокращённый синтаксис для преобразование литералов дат/времени:
update People set AgeCat = 'Old' where BirthDate < date '1-Jan-1943'
Заметьте, что вы можете не использовать даже краткий синтаксис преобразования в примере выше, т.к. Firebird поймёт из контекста (сравнение с полем типа DATE) как интерпретировать строку:
update People set AgeCat = 'Old' where BirthDate < '1-Jan-1943'
Но это не всегда возможно. Преобразование в примере ниже не может быть опущено, т.к. система будет пытаться преобразовать строку к числу. что бы вычесть из неё число:
select date 'today' - 7 from rdb$database
Вы можете применить преобразование типа к параметрам оператора:
cast (? as integer)
Это дает вам контроль над типом полей ввода. Обратите внимание, что с параметрами операторов, вы всегда должны использовать полный синтаксис преобразования, сокращённый синтаксис не поддерживается.
При преобразовании к домену должны быть удовлетворены любые ограничения (NOT NULL и/или CHECK) объявленные для домена, иначе преобразование не будет выполнено. Помните, что проверка CHECK проходит, если его вычисление даёт TRUE или UNKNOWN (NULL). Для следующих операторов:
create domain quint as int check (value >= 5000) select cast (2000 as quint) from rdb$database -- (1) select cast (8000 as quint) from rdb$database -- (2) select cast (null as quint) from rdb$database -- (3)
только (1) завершится с ошибкой.
При использовании модификатора TYPE OF выражение будет преобразовано к базовому типу домена, игнорируя любые ограничения. Для домена quint, объявленного выше, оба преобразования будут эквивалентны и оба будут успешно выполнены:
select cast (2000 as type of quint) from rdb$database select cast (2000 as int) from rdb$database
При использовании TYPE OF с (VAR)CHAR типом, его набор символов и порядок сортировки (collate) сохраняются.
create domain iso20 varchar(20) character set iso8859_1; create domain dunl20 varchar(20) character set iso8859_1 collate du_nl; create table zinnen (zin varchar(20)); commit; insert into zinnen values ('Deze'); insert into zinnen values ('Die'); insert into zinnen values ('die'); insert into zinnen values ('deze'); select cast(zin as type of iso20) from zinnen order by 1; -- returns Deze -> Die -> deze -> die select cast(zin as type of dunl20) from zinnen order by 1; -- returns deze -> Deze -> die -> Die
Если определение домена изменяется, то существующие преобразования к домену или его типу могут стать ошибочными. Если такие преобразования происходят в PSQL модулях, то их ошибки могут быть обнаружены. См. Поле RDB$VALID_BLR.
Разрешено преобразовывать выражение к типу столбца существующей таблицы или представления. При этом будет использован только сам тип, для строковых типов будет использован так же набор символов, но не последовательность сортировки. Ограничения и значения по умолчанию исходного столюца не применяются.
create table ttt ( s varchar(40) character set utf8 collate unicode_ci_ai ); commit; select cast ('Jag har många vänner' as type of column ttt.s) from rdb$database;
Для текстовых типов, набор символов и порядок сортировки сохраняются при преобразовании так же, как при преобразовании в домен. Тем не менее, из-за ошибки, порядок сортировки не всегда принимается во внимание при сравнении (например, в предикатах сравнения). В тех случаях, когда порядок сортировки важен, тщательно тестируйте свой код перед развёртыванием! Это ошибка исправлена в Firebird 3.
Если определение столбца изменяется, то существующие преобразования к его типу могут стать ошибочными. Если такие преобразования происходят в PSQL модулях, то их ошибки могут быть обнаружены. См. Поле RDB$VALID_BLR.
См. также: Явное преобразование типов данных.
Доступно в: DSQL, PSQL.
Синтаксис:
BIN_AND (number
[,number
...])
Параметры функции BIN_AND
number
Целое число.
Тип возвращаемого результата: INTEGER или BIGINT.
Функция BIN_AND возвращает результат побитовой операции AND (И) аргументов.
Доступно в: DSQL, PSQL.
Синтаксис:
BIN_NOT (number
)
Параметры функции BIN_NOT
number
Целое число.
Тип возвращаемого результата: INTEGER или BIGINT.
Функция BIN_NOT возвращает результат побитовой операции NOT над аргументом.
Доступно в: DSQL, PSQL.
Синтаксис:
BIN_OR (number
[,number
...])
Параметры функции BIN_OR
number
Целое число.
Тип возвращаемого результата: INTEGER или BIGINT.
Функция BIN_OR возвращает результат побитовой операции OR (ИЛИ) аргументов.
Доступно в: DSQL, PSQL.
Синтаксис:
BIN_SHL (number
,shift
)
Параметры функции BIN_SHL
number
Целое число.
shift
Количество бит, на которое смещается значение
number
.
Тип возвращаемого результата: BIGINT.
Функция BIN_SHL возвращает первый параметр, побитно смещённый влево на значение второго параметра.
См. также: BIN_SHR.
Доступно в: DSQL, PSQL.
Синтаксис:
BIN_SHR (number
,shift
)
Параметры функции BIN_SHR
number
Целое число.
shift
Количество бит на которое смещается значение number.
Тип возвращаемого результата: BIGINT.
Функция BIN_SHR возвращает первый параметр, побитно смещённый вправо на значение второго параметра.
Выполняемая операция является арифметическим сдвигом вправо (SAR), а это означает, что знак первого операнда всегда сохраняется.
См. также: BIN_SHL.
Доступно в: DSQL, PSQL.
Синтаксис:
CHAR_TO_UUID (ascii_uuid
)
Параметры функции CHAR_TO_UUID
ascii_uuid
36-символьное представление UUID. '-' (дефис) в положениях 9, 14, 19 и 24; допустимые шестнадцатеричные цифры в любых других позициях.
Тип возвращаемого результата: CHAR(16) CHARACTER SET OCTETS.
Функция CHAR_TO_UUID преобразует читабельную 36-ти символьную символику UUID к соответствующему 16-ти байтовому значению UUID.
Примеры:
Пример 7.47. Использование функции CHAR_TO_UUID
SELECT CHAR_TO_UUID('A0bF4E45-3029-2a44-D493-4998c9b439A3') FROM rdb$database -- returns A0BF4E4530292A44D4934998C9B439A3 (16-byte string) SELECT CHAR_TO_UUID('A0bF4E45-3029-2A44-X493-4998c9b439A3') FROM rdb$database -- error: -Human readable UUID argument for CHAR_TO_UUID must -- have hex digit at position 20 instead of "X (ASCII 88)"
См. также: GEN_UUID, UUID_TO_CHAR.
Доступно в: DSQL, PSQL.
Синтаксис:
GEN_UUID()
Тип возвращаемого результата: CHAR(16) CHARACTER SET OCTETS.
Функция возвращает универсальный уникальный идентификатор ID в виде 16-байтной строки символов. До версии Firebird 2.5.2 это была полностью случайная строка, что не отвечало требованиям стандарта RFC-4122. Начиная с версии 2.5.2, функция возвращает строку UUID 4-ой версии, где несколько битов зарезервированы, а остальные являются случайными.
Примеры:
Пример 7.48. Использование функции GEN_UUID
SELECT GEN_UUID() FROM RDB$DATABASE -- результат (до версии Firebird 2.5.2): 017347BFE212B2479C00FA4323B36320 (16-байтная строка) -- результат (начиная с версии Firebird 2.5.2): XXXXXXXX-XXXX-4XXX-YXXX-XXXXXXXXXXXX где 4 это номер версии, а Y может принимать значение 8, 9, A или B.
См. также: CHAR_TO_UUID, UUID_TO_CHAR.
Доступно в: DSQL, PSQL.
Синтаксис:
UUID_TO_CHAR (uuid
)
Параметры функции UUID_TO_CHAR
uuid
16-байтный UUID.
Тип возвращаемого результата: CHAR(36).
Функция UUID_TO_CHAR конвертирует 16-ти байтный UUID в его 36-ти знаковое ASCII человекочитаемое представление. Тип возвращаемого значения CHAR(36).
Примеры:
Пример 7.49. Использование функции UUID_TO_CHAR
SELECT UUID_TO_CHAR(GEN_UUID()) FROM RDB$DATABASE; SELECT UUID_TO_CHAR(x'876C45F4569B320DBCB4735AC3509E5F') FROM RDB$DATABASE; -- returns '876C45F4-569B-320D-BCB4-735AC3509E5F' SELECT UUID_TO_CHAR(gen_uuid()) FROM RDB$DATABASE; -- returns e.g. '680D946B-45FF-DB4E-B103-BB5711529B86' SELECT UUID_TO_CHAR('Firebird swings!') FROM RDB$DATABASE; -- returns '46697265-6269-7264-2073-77696E677321'
См. также: GEN_UUID, CHAR_TO_UUID.
Доступно в: DSQL, PSQL, ESQL.
Синтаксис:
GEN_ID(gen_name
,step
)
Параметры функции GEN_ID
gen_name
Имя генератора (последовательности).
step
Шаг приращения.
Тип возвращаемого результата: BIGINT.
Функция GEN_ID увеличивает значение генератора или последовательности и возвращает новое значение.
Если значение параметра step
меньше нуля, произойдёт
уменьшение значения генератора. Внимание! Следует быть крайне аккуратным при таких
манипуляциях в базе данных, они могут привести к потере целостности данных. Если
step
равен 0, функция не будет ничего делать со значением
генератора и вернёт его текущее значение.
Начиная с Firebird 2.0 для получения следующего значение последовательности (генератора) стало доступно использование оператора NEXT VALUE FOR.
Примеры:
См. также: NEXT VALUE FOR, SEQUENCE (GENERATOR), ALTER SEQUENCE, SET GENERATOR.
Доступно в: DSQL, PSQL.
Синтаксис:
COALESCE(expr1
,expr2
[,exprN
...])
Параметры функции COALESCE
expr1
, expr2
...
exprN
Выражения любого совместимого типа.
Тип возвращаемого результата: тот же что и первый аргумент функции expr1
, если все
выражения имеют одинаковый тип, в противном случае происходит преобразование в тип с
наибольшей вместимостью.
Функция COALESCE принимает два или более аргумента возвращает значение первого NOT NULL аргумента. Если все аргументы имеют значение NULL, то и результат будет NULL.
Примеры:
Пример 7.51. Использование функции COALESCE
SELECT COALESCE(PE.NICKNAME, PE.FIRSTNAME, 'Mr./Mrs.') || ' ' || PE.LASTNAME AS FULLNAME FROM PERSONS PE
В данном примере предпринимается попытка использовать все имеющиеся данные для составления полного имени. Выбирается поле NICKNAME из таблицы PERSONS. Если оно имеет значение NULL, то берётся значение из поля FIRSTNAME. Если и оно имеет значение NULL, то используется строка 'Mr./Mrs.'. Затем к значению функции COALESCE фамилия (поле LASTNAME). Обратите внимание, что эта схема нормально работает, только если выбираемые поля имеют значение NULL или не пустое значение: если одно из них является пустой строкой, то именно оно и возвратится в качестве значения функции COALESCE.
Пример 7.52. Использование функции COALESCE с агрегатными функциями
-- в случае получения при суммировании NULL, вернёт 0. SELECT coalesce (sum (q), 0) FROM bills WHERE ...
См. также: CASE.
Доступно в: DSQL, PSQL.
Синтаксис:
DECODE(testexpr
,expr1
,result1
[,expr2
,result2
...] [,defaultresult
])
эквивалентная конструкция CASE
CASEtestexpr
WHENexpr1
THENresult1
[WHENexpr2
THENresult2
...] [ELSEdefaultresult
] END
Параметры функции DECODE
testexpr
Выражения любого совместимого типа, которое сравнивается с выражениями
expr1
, expr2
...
exprN
expr1
, expr2
...
exprN
Выражения любого совместимого типа, с которыми сравнивают с выражением
testexpr
.
result1
, result2
...
resultN
Возвращаемые выражения любого типа.
defaultresult
Выражения, возвращаемое если ни одно из условий не было выполнено.
Тип возвращаемого результата: тот же что и первый результат result1
, если все выражения
result
имеют одинаковый тип, в противном случае происходит
преобразование в тип с наибольшей вместимостью.
Данная функция эквивалентна конструкции Простой CASE, в которой заданное выражение сравнивается с другими выражениями до нахождения совпадения. Результатом является значение, указанное после выражения, с которым найдено совпадение. Если совпадений не найдено, то возвращается значение по умолчанию (если оно, конечно, задано – в противном случае возвращается NULL).
Совпадение эквивалентно оператору "=", т.е. если testexpr
имеет значение NULL, то он не соответствует ни одному из
expr
, даже тем, которые имеют значение NULL.
Примеры:
Пример 7.53. Использование функции DECODE
SELECT name, age, decode (upper(sex), 'M', 'М', 'F', 'Ж', 'не указано') AS sexname, UID FROM people
См. также: CASE.
Доступно в: DSQL, PSQL.
Синтаксис:
IIF(<condition>
,resultT
,resultF
)
Параметры функции IIF
condition
Выражение логического типа.
resultT
Возвращаемое значение, если condition
является
истинным.
resultF
Возвращаемое значение, если condition
является
ложным.
Тип возвращаемого результата: тот же что и аргумент функции resultT
, если выражения
resultT
и resultF
имеют
одинаковый тип, в противном случае происходит преобразование в тип с наибольшей
вместимостью.
Функция IIF имеет три аргумента. Если первый аргумент является истиной, то результатом будет второй параметр, в противном случае результатом будет третий параметр.
По сути, функция IIF это короткая запись оператора CASE
CASE WHEN<condition>
THENresultT
ELSEresultF
END
Оператор IIF также можно сравнить в тройным оператором "?:" в C-подобных языках.
Примеры:
См. также: CASE.
Доступно в: DSQL, PSQL.
Синтаксис:
MAXVALUE(expr1
[,exprN
...])
Параметры функции MAXVALUE
expr1
... exprN
Выражения любого совместимого типа.
Тип возвращаемого результата: тот же что и первый аргумент функции expr1
.
Возвращает максимальное значение из входного списка чисел, строк или параметров с типом DATE/TIME/TIMESTAMP.
Если один или более входных параметров имеют значение NULL, то результатом функции MAXVALUE тоже будет NULL в отличие от агрегатной функции MAX.
Примеры:
Пример 7.55. Использование функции MAXVALUE
SELECT MAXVALUE(PRICE_1, PRICE_2) AS PRICE FROM PRICELIST
См. также: MINVALUE.
Доступно в: DSQL, PSQL.
Синтаксис:
MINVALUE(expr1
[,exprN
...])
Параметры функции MINVALUE
expr1
... exprN
Выражения любого совместимого типа.
Тип возвращаемого результата: тот же что и первый аргумент функции expr1
.
Возвращает минимальное значение из входного списка чисел, строк или параметров с типом DATE/TIME/TIMESTAMP.
Если один или более входных параметров имеют значение NULL, то результатом функции MINVALUE тоже будет NULL в отличие от агрегатной функции MIN.
Примеры:
Пример 7.56. Использование функции MINVALUE
SELECT MINVALUE(PRICE_1, PRICE_2) AS PRICE FROM PRICELIST
См. также: MAXVALUE.
Доступно в: DSQL, PSQL.
Синтаксис:
NULLIF(expr1
,expr2
)
Параметры функции NULLIF
expr1
, expr2
Выражения любого совместимого типа.
Тип возвращаемого результата: тот же что и первый аргумент функции expr1
.
Функция возвращает значение первого аргумента, если он неравен второму. В случае равенства аргументов возвращается NULL.
Примеры:
Пример 7.57. Использование функции NULLIF
/* запрос вернёт среднее значение поля weight по таблице, за исключением строк, где он не указан (равен -1). Если бы не было этой функции простой оператор avg(weight) вернул бы некорректное значение */ SELECT AVG(NULLIF(weight, -1)) FROM cargo;
Агрегатные функции выполняют вычисление на наборе значений и возвращают одиночное значение. Агрегатные функции, за исключением COUNT, не учитывают значения NULL. Агрегатные функции часто используются совместно с предложением GROUP BY.
Агрегатные функции могут быть использованы в качестве выражений только в следующих случаях:
Список выбора инструкции SELECT (вложенный или внешний запрос);
Предложение HAVING.
Доступно в: DSQL.
Синтаксис:
AVG([ALL | DISTINCT] <expr>
)
Параметры функции AVG
expr
Выражение. Может содержать столбец таблицы, константу, переменную, выражение, неагрегатную функцию или UDF, которая возвращает числовой тип данных. Агрегатные функции в качестве выражения не допускаются.
Тип возвращаемого результата: тот же что и аргумент функции expr
.
Функция AVG возвращает среднее значение для группы. Значения NULL пропускаются.
Параметр ALL применяет агрегатную функцию ко всем значениям. ALL является параметром по умолчанию. Параметр DISTINCT указывает на то, что функция AVG будет выполнена только для одного экземпляра каждого уникального значения, независимо от того, сколько раз встречается это значение.
В случае если выборка записей пустая или содержит только значения NULL, результат будет содержать NULL.
Примеры:
См. также: SELECT.
Доступно в: DSQL.
Синтаксис:
COUNT({[ALL | DISTINCT] <expr>
| *})
Параметры функции COUNT
expr
Выражение. Может содержать столбец таблицы, константу, переменную, выражение, неагрегатную функцию или UDF. Агрегатные функции в качестве выражения не допускаются.
Тип возвращаемого результата: INTEGER.
Функция COUNT возвращает количество значений в группе, которые не являются NULL.
При указании DISTINCT из выборки устраняются дубликаты, ALL является значением по умолчанию для всех выборки значений не NULL.
Если вместо выражения expr
указана звёздочка (*), то будут
подсчитаны все строки. Функция COUNT(*) не принимает параметры и не может использоваться с
ключевым словом DISTINCT. Для функции COUNT(*) не нужен параметр
expr
, так как по определению она не использует сведения о
каких-либо конкретных столбцах. Функция COUNT(*) возвращает количество строк в указанной
таблице, не отбрасывая дублированные строки. Она подсчитывает каждую строку отдельно. При
этом учитываются и строки, содержащие значения NULL.
Для пустой выборки данных или если при выборке окажутся одни значения, содержащие NULL, функция возвратит значение равное 0.
Примеры:
Пример 7.59. Использование функции COUNT
SELECT dept_no, COUNT(*) AS cnt, COUNT(DISTINCT name) AS cnt_name FROM employee GROUP BY dept_no
См. также: SELECT.
Доступно в: DSQL.
Синтаксис:
LIST([ALL | DISTINCT]<expr>
[,separator
])
Параметры функции LIST
expr
Выражение. Может содержать столбец таблицы, константу, переменную, выражение, неагрегатную функцию или UDF, которая возвращает строковый тип данных или BLOB. Поля типа дата / время и числовые преобразуются к строке. Агрегатные функции в качестве выражения не допускаются.
separator
Разделитель. Выражение строкового типа. По умолчанию разделителем является запятая.
Тип возвращаемого результата: BLOB.
Функция LIST возвращает строку, содержащую значения элементов выборки, которые не равны NULL. При пустой выборке функция возвратит NULL. Тип возвращаемого значения текстовый BLOB за исключением тех случаев, когда выражением являются BLOB других подтипов.
ALL является опцией по умолчанию. При ней обрабатываются все значения в выборке, не содержащие NULL. При указании DISTINCT из выборки устраняются дубликаты.
Значения выражения expr
и разделитель
separator
поддерживают тип данных BLOB любого размера и набора
символов. Поля типа дата / время и числовые перед проведением операции конкатенации
преобразуются в строки.
Порядок конкатенации строк определяется порядком чтения записей из источников, который в общем случае не определён. Для придания списку необходимого порядка вы можете предварительно упорядочить источник данных, например, с помощью производной таблицы.
Примеры:
Пример 7.60. Использование функции LIST
-- Получение списка, порядок не определён SELECT LIST (display_name, '; ') FROM GR_WORK; -- Получение списка в алфавитном порядке SELECT LIST (display_name, '; ') FROM (SELECT display_name FROM GR_WORK ORDER BY display_name);
См. также: SELECT.
Доступно в: DSQL.
Синтаксис:
MAX([ALL | DISTINCT] <expr>
)
Параметры функции MAX
expr
Выражение. Может содержать столбец таблицы, константу, переменную, выражение, неагрегатную функцию или UDF. Агрегатные функции в качестве выражения не допускаются.
Тип возвращаемого результата: тот же что и аргумент функции expr
.
Функция MAX возвращает максимальный элемент выборки, которые не равны NULL. При пустой выборке, или при выборке из одних NULL функция возвратит NULL. Если аргумент функции строка, то функция вернёт значение, которое окажется последним в сортировке при применении COLLATE.
Параметр DISTINCT не имеет смысла при использовании функцией MAX и доступен только для совместимости со стандартом.
Примеры:
Доступно в: DSQL.
Синтаксис:
MIN([ALL | DISTINCT] <expr>
)
Параметры функции MIN
expr
Выражение. Может содержать столбец таблицы, константу, переменную, выражение, неагрегатную функцию или UDF. Агрегатные функции в качестве выражения не допускаются.
Тип возвращаемого результата: тот же что и аргумент функции expr
.
Функция MIN возвращает минимальный элемент выборки, которые не равны NULL. При пустой выборке, или при выборке из одних NULL функция возвратит NULL. Если аргумент функции строка, то функция вернёт значение, которое окажется первым в сортировке при применении COLLATE.
Параметр DISTINCT не имеет смысла при использовании функцией MIN и доступен только для совместимости со стандартом.
Примеры:
Доступно в: DSQL.
Синтаксис:
SUM([ALL | DISTINCT] <expr>
)
Параметры функции SUM
expr
Выражение. Может содержать столбец таблицы, константу, переменную, выражение, неагрегатную функцию или UDF, которая возвращает числовой тип данных. Агрегатные функции в качестве выражения не допускаются.
Тип возвращаемого результата: тот же что и аргумент функции expr
.
Функция SUM возвращает сумму элементов выборки, которые не равны NULL. При пустой выборке, или при выборке из одних NULL функция возвратит NULL.
ALL является опцией по умолчанию. При ней обрабатываются все значения из выборки, не содержащие NULL. При указании DISTINCT из выборки устраняются дубликаты, после осуществляется подсчёт.
Примеры:
См. также: SELECT.
Всё в Firebird выполняется в рамках транзакций. Транзакция — логическая единица изолированной работы группы последовательных операций над базой данных. Изменения над данными остаются обратимыми до тех пор, пока клиентское приложение не выдаст серверу инструкцию COMMIT.
Firebird имеет небольшое количество SQL операторов, которые могут использоваться клиентскими приложениями для старта, управления, подтверждения или отмены транзакций, но достаточное для всех задач над базой данных:
SET TRANSACTION — задание параметров транзакции и её старт;
COMMIT — завершение транзакции и сохранение изменений;
ROLLBACK — отмена изменений произошедший в рамках транзакции;
SAVEPOINT — установка точки сохранения для частичного отката изменений, если это необходимо;
RELEASE SAVEPOINT — удаление точки сохранения.
Назначение: Задаёт параметры транзакции и стартует её.
Доступно в: DSQL, ESQL.
Синтаксис:
SET TRANSACTION [NAMEtr_name
] [READ WRITE | READ ONLY] [[ISOLATION LEVEL] { SNAPSHOT [TABLE STABILITY] | READ COMMITTED [[NO] RECORD_VERSION] }] [NO WAIT | WAIT [LOCK TIMEOUTseconds
]] [NO AUTO UNDO] [IGNORE LIMBO] [RESTART REQUESTS] [RESERVING<tables>
| USING<dbhandles>
]<tables>
::=<table_spec>
[,<table_spec>
...]<table_spec>
::=tablename
[,tablename
...] [FOR [SHARED | PROTECTED] {READ | WRITE}]<dbhandles>
::=dbhandle
[,dbhandle
...]
Параметры оператора SET TRANSACTION
tr_name
Имя транзакции. Доступно только в ESQL.
seconds
Время ожидания оператора (statement) в секундах при возникновении конфликта.
tables
Список таблиц для резервирования.
dbhandles
Список баз данных, к которым база данных может получить доступ. Доступно только в ESQL.
table_spec
Спецификация резервирования таблицы.
tablename
Имя таблицы для резервирования.
dbhandle
Хендл базы данных, к которой транзакция может получить доступ. Доступно только в ESQL.
Оператор SET TRANSACTION задаёт параметры транзакции и стартует её. Старт транзакции осуществляется только клиентскими приложениями, но не сервером (за исключением автономных транзакций и некоторых фоновых системных потоков/процессов, например, таких как sweep).
Каждое клиентское приложение может запускать произвольное количество одновременно выполняющихся транзакций. Фактически есть ограничение на общее количество выполняемых транзакций во всех клиентских приложениях, работающих с одной конкретной базой данных с момента последнего восстановления базы данных с резервной копии или с момента первоначального создания базы данных. Это количество равняется числу 231 – 1, то есть 2 147 483 647.
Все предложения в операторе SET TRANSACTION
являются необязательными. Если в
операторе запуска транзакции на выполнение не задано никакого предложения, то
предполагается старт транзакции со значениями всех характеристик по умолчанию (режим
доступа, режим разрешения блокировок и уровень изолированности).
По умолчанию транзакция стартует со следующими характеристиками.
SET TRANSACTION READ WRITE WAIT ISOLATION LEVEL SNAPSHOT;
При старте со стороны клиента любой транзакции (заданной явно или по умолчанию) сервер передаёт клиенту дескриптор транзакции (целое число). На стороне сервера транзакциям последовательно присваиваются номера. Этот номер средствами SQL можно получить, используя контекстную переменную CURRENT_TRANSACTION.
Основными характеристиками транзакции являются:
режим доступа к данным (READ WRITE, READ ONLY);
режим разрешения блокировок (WAIT, NO WAIT) с возможным дополнительным уточнением LOCK TIMEOUT;
уровень изоляции (READ COMMITTED, SNAPSHOT, TABLE STABILITY);
средства резервирования или освобождения таблиц (предложение RESERVING).
Необязательное предложение NAME задаёт имя транзакции. Предложение NAME
доступно только в Embedded SQL. Если предложение NAME не указано, то
оператор SET TRANSACTION
применяется к транзакции по умолчанию. За счёт
именованных транзакций позволяется одновременный запуск нескольких активных
транзакций в одном приложении. При этом должна быть объявлена и
инициализирована одноименная переменная базового языка. В DSQL, это
ограничение предотвращает динамическую спецификацию имён транзакций.
Для транзакций существует два режима доступа к данным базы данных: READ WRITE и READ ONLY.
При режиме доступа READ WRITE операции в контексте данной транзакции могут быть как операциями чтения, так и операциями изменения данных. Это режим по умолчанию.
В режиме READ ONLY в контексте данной транзакции могут выполняться только операции выборки данных SELECT. Любая попытка изменения данных в контексте такой транзакции приведёт к исключениям базы данных. Однако это не относиться к глобальным временным таблицам (GTT), которые разрешено модифицировать в READ ONLY транзакциях.
В Firebird API для режимов доступа предусмотрены следующие константы:
isc_tpb_write
соответсвует режиму READ WRITE
,
isc_tpb_read
— READ ONLY
.
При работе с одной и той же базой данных нескольких клиентских приложений могут возникать блокировки. Блокировки могут возникать, когда одна транзакция вносит неподтверждённые изменения в строку таблицы или удаляет строку, а другая транзакция пытается изменять или удалять эту же строку. Такие блокировки называются конфликтом обновления.
Блокировки также могут возникнуть и в других ситуациях при использовании некоторых уровней изоляции транзакций.
Существуют два режима разрешения блокировок: WAIT и NO WAIT.
В режиме WAIT
(режим по умолчанию) при появлении
конфликта с параллельными транзакциями, выполняющими конкурирующие
обновления данных в той же базе данных, такая транзакция будет ожидать
завершения конкурирующей транзакции путём её подтверждения (COMMIT) или
отката (ROLLBACK). Иными словами, клиентское приложение будет переведено
в режим ожидания до момента разрешения конфликта.
Если для режима WAIT
задать предложение LOCK
TIMEOUT
, то ожидание будет продолжаться только указанное в
этом предложении количество секунд. По истечении этого срока будет
выдано сообщение об ошибке: "Lock time-out on wait
transaction" (Истечение времени ожидания блокировки для транзакции
WAIT).
Этот режим даёт несколько отличные формы поведения в зависимости от уровня изоляции транзакций.
В Firebird API режиму WAIT
соответсвует константа
isc_tpb_wait
.
Уровень изолированности транзакций — значение, определяющее уровень, при котором в транзакции допускаются несогласованные данные, то есть степень изолированности одной транзакции от другой. Изменения, внесённые некоторым оператором, будут видны всем последующим операторам, запущенным в рамках этой же транзакции, независимо от её уровня изолированности. Изменения произведённые в рамках другой транзакции остаются невидимыми для текущей транзакции до тех пор пока они не подтверждены. Уровень изолированности, а иногда, другие атрибуты, определяет, как транзакции будут взаимодействовать с другой транзакцией, которая хочет подтвердить изменения.
Необязательное предложение ISOLATION LEVEL задаёт уровень изолированности запускаемой транзакции. Это самая важная характеристика транзакции, которая определяет её поведение по отношению к другим одновременно выполняющимся транзакциям.
Существует три уровня изолированности транзакции:
SNAPSHOT
SNAPSHOT TABLE STABILITY
READ COMMITTED с двумя уточнениями (NO RECORD_VERSION и RECORD_VERSION)
Уровень изолированности SNAPSHOT
(уровень изолированности по
умолчанию) означает, что этой транзакции видны лишь те изменения,
фиксация которых произошла не позднее момента старта этой транзакции.
Любые подтверждённые изменения, сделанные другими конкурирующими
транзакциями, не будут видны в такой транзакции в процессе ее активности
без её перезапуска. Чтобы увидеть эти изменения, нужно завершить
транзакцию (подтвердить её или выполнить полный откат, но не откат на
точку сохранения) и запустить транзакцию заново.
Изменения, вносимые автономными транзакциями, также не будут видны
в контексте той ("внешней") транзакции, которая запустила
эти автономные транзакции, если она работает в режиме SNAPSHOT
.
В Firebird API режиму изолированности SNAPSHOT
соответсвует константа isc_tpb_concurrency
.
Уровень изоляции транзакции SNAPSHOT TABLE STABILITY
позволяет, как и
в случае SNAPSHOT
, также видеть только те изменения, фиксация которых
произошла не позднее момента старта этой транзакции. При этом после
старта такой транзакции в других клиентских транзакциях невозможно
выполнение изменений ни в каких таблицах этой базы данных, уже
каким-либо образом измененных первой транзакцией. Все такие попытки в
параллельных транзакциях приведут к исключениям базы данных.
Просматривать любые данные другие транзакции могут совершенно
свободно.
При помощи предложения резервирования RESERVING
можно разрешить
другим транзакциям изменять данные в некоторых таблицах.
Если на момент старта клиентом транзакции с уровнем изоляции SNAPSHOT
TABLE STABILITY
какая-нибудь другая транзакция выполнила
неподтверждённое изменение данных любой таблицы базы данных, то запуск
транзакции с таким уровнем изоляции приведёт к ошибке базы данных.
В Firebird API режиму изолированности SNAPSHOT TABLE
STABILITY
соответсвует константа
isc_tpb_consistency
.
Уровень изолированности READ COMMITTED
позволяет в транзакции без её
перезапуска видеть все подтверждённые изменения данных базы данных,
выполненные в других параллельных транзакциях. Неподтверждённые
изменения не видны в транзакции и этого уровня изоляции.
Для получения обновлённого списка строк интересующей таблицы
необходимо лишь повторное выполнение оператора SELECT в рамках активной
транзакции READ COMMITTED
без её перезапуска.
В Firebird API режиму изолированности READ COMMITTED
соответсвует константа isc_tpb_read_committed
.
Для этого уровня изолированности можно указать один из двух
значений дополнительной характеристики в зависимости от желаемого
способа разрешения конфликтов: RECORD_VERSION
и
NO RECORD_VERSION
. Как видно из их имён они
являются взаимоисключающими.
NO RECORD_VERSION
(значение по умолчанию)
является в некотором роде механизмом двухфазной
блокировки. В этом случае транзакция не может прочитать
любую запись, которая была изменена параллельной
активной (неподтвержденной) транзакцией.
Если указана стратегия разрешения блокировок NO
WAIT
, то будет немедленно выдано
соответствующее исключение.
Если указана стратегия разрешения блокировок
WAIT
, то это приведёт к ожиданию
завершения или откату конкурирующей транзакции. Если
конкурирующая транзакция откатывается, или, если она
завершается и её идентификатор старее (меньше), чем
идентификатор текущей транзакции, то изменения в текущей
транзакции допускаются. Если конкурирующая транзакция
завершается и её идентификатор новее (больше), чем
идентификатор текущей транзакции, то будет выдана ошибка
конфликта блокировок.
В Firebird API для способа разрешения конфликтов
NO RECORD_VERSION
соответсвует
константа isc_tpb_no_rec_version
.
При задании RECORD_VERSION
транзакция
всегда читает последнюю подтверждённую версию записей
таблиц, независимо от того, существуют ли изменённые и
ещё не подтверждённые версии этих записей. В этом случае
режим разрешения блокировок (WAIT
или
NO WAIT
) никак не влияет на поведение
транзакции при её старте.
В Firebird API для способа разрешения конфликтов
RECORD_VERSION
соответсвует
константа isc_tpb_rec_version
.
При использовании опции NO AUTO UNDO оператор ROLLBACK только помечает
транзакцию как отменённую без удаления созданных в этой транзакции версий,
которые будут удалены позднее в соответствии с выбранной политикой сборки
мусора (см. параметр GCPolicy
в
firebird.conf
).
Эта опция может быть полезна при выполнении транзакции, в рамках которой производится много отдельных операторов, изменяющих данные, и при этом есть уверенность, что эта транзакция будет чаще всего завершаться успешно, а не откатываться.
Для транзакций, в рамках которых не выполняется никаких изменений, опция NO AUTO UNDO игнорируется.
При указании опции IGNORE LIMBO игнорируются записи, создаваемые "потерянными" (т.е. не завершёнными) транзакциями (limbo transaction). Транзакции считается "потерянной", если не завершён второй этап двухфазного подтверждения (two-phase commit).
Предложение RESERVING в операторе SET TRANSACTION резервирует указанные в списке таблицы. Резервирование запрещает другим транзакциям вносить в эти таблицы изменения или (при определённых установках характеристик предложения резервирования) даже читать данные из этих таблиц, в то время как выполняется данная транзакция. Либо, наоборот, в этом предложении можно указать список таблиц, в которые параллельные транзакции могут вносить изменения, даже если запускается транзакция с уровнем изоляции SNAPSHOT TABLE STABILITY.
В одном предложении резервирования можно указать произвольное количество резервируемых таблиц используемой базы данных.
Если опущено одно из ключевых слов SHARED или PROTECTED, то предполагается SHARED. Если опущено все предложение FOR, то предполагается FOR SHARED READ. Варианты осуществления резервирования таблиц по их названиям не являются очевидными.
Таблица 8.1. Совместимости различных блокировок
SHARED READ | SHARED WRITE | PROTECTED READ | PROTECTED WRITE | |
---|---|---|---|---|
SHARED READ | да | да | да | да |
SHARED WRITE | да | да | нет | нет |
PROTECTED READ | да | нет | да | нет |
PROTECTED WRITE | да | нет | нет | нет |
Для транзакции запущенной в режиме изолированности SNAPSHOT для таблиц, указанных в предложении RESERVING, в параллельных транзакциях в зависимости от их уровня изоляции допустимы при различных способах их резервирования следующие варианты поведения:
SHARED READ — не оказывает никакого влияния на выполнение параллельных транзакций;
SHARED WRITE — на поведение параллельных транзакций с уровнями изолированности SNAPSHOT и READ COMMITTED не оказывает никакого влияния, для транзакций с уровнем изолированности SNAPSHOT TABLE STABILITY запрещает не только запись, но также и чтение данных из указанных таблиц;
PROTECTED READ — допускает только чтение данных из резервируемых таблиц для параллельных транзакций с любым уровнем изолированности, попытка внесения изменений приводит к исключению базы данных;
PROTECTED WRITE — для параллельных транзакций с уровнями изолированности SNAPSHOT и READ COMMITTED запрещает запись в указанные таблицы, для транзакций с уровнем изолированности SNAPSHOT TABLE STABILITY запрещает также и чтение данных из резервируемых таблиц.
Для транзакции запущенной в режиме изолированности SNAPSHOT TABLE STABILITY для таблиц, указанных в предложении RESERVING, в параллельных транзакциях в зависимости от их уровня изолированности допустимы при различных способах их резервирования следующие варианты поведения:
SHARED READ — позволяет всем параллельным транзакциям независимо от их уровня изолированности не только читать, но и выполнять любые изменения в резервируемых таблицах (если параллельная транзакция имеет режим доступа READ WRITE);
SHARED WRITE — для всех параллельных транзакций с уровнем доступа READ WRITE и с уровнями изолированности SNAPSHOT и READ COMMITTED позволяет читать данные из таблиц и писать данные в указанные таблицы, для транзакций с уровнем изолированности SNAPSHOT TABLE STABILITY запрещает не только запись, но также и чтение данных из указанных таблиц;
PROTECTED READ — допускает только лишь чтение данных из резервируемых таблиц для параллельных транзакций с любым уровнем изолированности;
PROTECTED WRITE — для параллельных транзакций с уровнями изолированности SNAPSHOT и READ COMMITTED запрещает запись в указанные таблицы, для транзакций с уровнем изолированности SNAPSHOT TABLE STABILITY запрещает также и чтение данных из резервируемых таблиц.
Для транзакции запущенной в режиме изолированности READ COMMITTED для таблиц, указанных в предложении RESERVING, в параллельных транзакциях в зависимости от их уровня изоляции допустимы при различных способах их резервирования следующие варианты поведения:
SHARED READ — позволяет всем параллельным транзакциям независимо от их уровня изолированности не только читать, но и выполнять любые изменения в резервируемых таблицах (при уровне доступа READ WRITE);
SHARED WRITE — для всех транзакций с уровнем доступа READ WRITE и с уровнями изолированности SNAPSHOT и READ COMMITTED позволяет читать и писать данные в указанные таблицы, для транзакций с уровнем изолированности SNAPSHOT TABLE STABILITY запрещает не только запись, но также и чтение данных из указанных таблиц;
PROTECTED READ — допускает только чтение данных из резервируемых таблиц для параллельных транзакций с любым уровнем изолированности;
PROTECTED WRITE — для параллельных транзакций с уровнями изолированности SNAPSHOT и READ COMMITTED разрешает только чтение данных и запрещает запись в указанные в данном списке таблицы, для транзакций с уровнем изолированности SNAPSHOT TABLE STABILITY запрещает не только изменение данных, но и чтение данных из резервируемых таблиц.
Предложение USING может быть использовано для сохранения системных ресурсов за счёт ограничения количества баз данных, к которым имеет доступ транзакция. Доступно только в Embedded SQL.
Назначение: Подтверждение транзакции.
Доступно в: DSQL, ESQL.
Синтаксис:
COMMIT [WORK] [TRANSACTION tr_name
]
[RELEASE] [RETAIN [SNAPSHOT]];
Параметры оператора COMMIT
tr_name
Имя транзакции. Доступно только в ESQL.
Оператор COMMIT подтверждает все изменения в данных, выполненные в контексте данной транзакции (добавления, изменения, удаления). Новые версии записей становятся доступными для других транзакций, и если предложение RETAIN не используется освобождаются все ресурсы сервера, связанные с выполнением данной транзакции.
Если в процессе подтверждения транзакции возникли ошибки в базе данных, то транзакция не подтверждается. Пользовательская программа должна обработать ошибочную ситуацию и заново подтвердить транзакцию или выполнить ее откат.
Необязательное предложение TRANSACTION задаёт имя транзакции. Предложение TRANSACTION доступно только в Embedded SQL. Если предложение TRANSACTION не указано, то оператор COMMIT применяется к транзакции по умолчанию.
За счёт именованных транзакций позволяется одновременный запуск нескольких активных транзакций в одном приложении. При этом должна быть объявлена и инициализирована одноименная переменная базового языка. В DSQL, это ограничение предотвращает динамическую спецификацию имён транзакций.
Необязательное ключевое слово WORK может быть использовано лишь для совместимости с другими системами управления реляционными базами данных.
Ключевое слово RELEASE доступно только в Embedded SQL. Оно позволяет отключиться ото всех баз данных после завершения текущей транзакции. RELEASE поддерживается только для обратной совместимости со старыми версиями INTERBASE. В настоящее время вместо него используется оператор ESQL DISCONNECT.
Если используется предложение RETAIN [SNAPSHOT], то выполняется так называемое мягкое (soft) подтверждение. Выполненные действия в контексте данной транзакции фиксируются в базе данных, а сама транзакция продолжает оставаться активной, сохраняя свой идентификатор, а также состояние курсоров, которое было до мягкой фиксации транзакции. В этом случае нет необходимости опять стартовать транзакцию и заново выполнять оператор SELECT для получения данных.
Если уровень изоляции такой транзакции SNAPSHOT или SNAPSHOT TABLE STABILITY, то после мягкого подтверждения транзакция продолжает видеть то состояние базы данных, которое было при первоначальном запуске транзакции, то есть клиентская программа не видит новых подтверждённых результатов изменения данных других транзакций. Кроме того, мягкое подтверждение не освобождает ресурсов сервера (открытые курсоры не закрываются).
Для транзакций, которые выполняют только чтение данных из базы данных, рекомендуется также использовать оператор COMMIT, а не ROLLBACK, поскольку этот вариант требует меньшего количества ресурсов сервера и улучшает производительность всех последующих транзакций.
См. также: SET TRANSACTION, ROLLBACK.
Назначение: Откат транзакции.
Доступно в: DSQL, ESQL.
Синтаксис:
ROLLBACK [WORK] [TRANSACTION tr_name
]
[RETAIN [SNAPSHOT] | TO SAVEPOINT sp_name] [RELEASE];
Параметры оператора ROLLBACK
tr_name
Имя транзакции. Доступно только в ESQL.
sp_name
Имя точки сохранения. Доступно только в DSQL.
Оператор ROLLBACK отменяет все изменения данных базы данных (добавление, изменение, удаление), выполненные в контексте этой транзакции. Оператор ROLLBACK никогда не вызывает ошибок. Если не указано предложение RETAIN, то при его выполнении освобождаются все ресурсы сервера, связанные с выполнением данной транзакции.
Необязательное предложение TRANSACTION задаёт имя транзакции. Предложение TRANSACTION доступно только в Embedded SQL. Если предложение TRANSACTION не указано, то оператор ROLLBACK применяется к транзакции по умолчанию.
За счёт именованных транзакций позволяется одновременный запуск нескольких активных транзакций в одном приложении. При этом должна быть объявлена и инициализирована одноименная переменная базового языка. В DSQL, это ограничение предотвращает динамическую спецификацию имён транзакций.
Необязательное ключевое слово WORK может быть использовано лишь для совместимости с другими системами управления реляционными базами данных.
Ключевое слово RETAIN указывает, что все действия по изменению данных в контексте этой транзакции, отменяются, а сама транзакция продолжает оставаться активной, сохраняя свой идентификатор, а также состояние курсоров, которое было до мягкой фиксации транзакции. Таким образом, выделенные ресурсы для транзакции не освобождаются.
Для уровней изоляции SNAPSHOT и SNAPSHOT TABLE STABILITY состояние базы данных остаётся в том виде, которое база данных имела при первоначальном старте такой транзакции, однако в случае уровня изоляции READ COMMITTED база данных будет иметь вид, соответствующий новому состоянию на момент выполнения оператора ROLLBACK RETAIN. В случае отмены транзакции с сохранением её контекста нет необходимости заново выполнять оператор SELECT для получения данных из таблицы.
См. также: SET TRANSACTION, COMMIT.
Необязательное предложение TO SAVEPOINT в операторе ROLLBACK задаёт имя точки сохранения, на которую происходит откат. В этом случае отменяются все изменения, произошедшие в рамках транзакции, начиная с созданной точки сохранения (SAVEPOINT).
Оператор ROLLBACK TO SAVEPOINT выполняет следующие операции:
Все изменения в базе данных, выполненные в рамках транзакции начиная с созданной точки сохранения, отменяются. Пользовательские переменные, заданные с помощью функции RDB$SET_CONTEXT() остаются неизменными;
Все точки сохранения, создаваемые после названной, уничтожаются. Все более ранние точки сохранения, как сама точка сохранения, остаются. Это означает, что можно откатываться к той же точке сохранения несколько раз;
Все явные и неявные блокированные записи, начиная с точки сохранения, освобождаются. Другие транзакции, запросившие ранее доступ к строкам, заблокированным после точки сохранения, должны продолжать ожидать, пока транзакция не фиксируется или откатывается. Другие транзакции, которые ещё не запрашивали доступ к этим строкам, могут запросить и сразу же получить доступ к разблокированным строкам.
См. также: SAVEPOINT.
Назначение: Создание точки сохранения.
Доступно в: DSQL.
Синтаксис:
SAVEPOINT sp_name
Параметры оператора SAVEPOINT
sp_name
Имя точки сохранения. Должно быть уникальным в рамках транзакции.
Оператор SAVEPOINT создаёт SQL 99 совместимую точку сохранения, к которой можно позже откатывать работу с базой данных, не отменяя все действия, выполненные с момента старта транзакции. Механизмы точки сохранения также известны под термином "вложенные транзакции" ("nested transactions").
Если имя точки сохранения уже существует в рамках транзакции, то существующая точка сохранения будет удалена, и создаётся новая с тем же именем.
Для отката изменений к точке сохранения используется оператор ROLLBACK TO SAVEPOINT.
Внутренний механизм точек сохранения может использовать большие объёмы памяти, особенно если вы обновляете одни и те же записи многократно в одной транзакции. Если точка сохранения уже не нужна, но вы ещё не готовы закончить транзакцию, то можно ее удалить оператором RELEASE SAVEPOINT, тем самым освобождая ресурсы.
Примеры:
Пример 8.1. DSQL сессия с использованием точек сохранения
CREATE TABLE TEST (ID INTEGER); COMMIT; INSERT INTO TEST VALUES (1); COMMIT; INSERT INTO TEST VALUES (2); SAVEPOINT Y; DELETE FROM TEST; SELECT * FROM TEST; -- возвращает пустую строку ROLLBACK TO Y; SELECT * FROM TEST; -- возвращает две строки ROLLBACK; SELECT * FROM TEST; -- возвращает одну строку
См. также: ROLLBACK TO SAVEPOINT, RELEASE SAVEPOINT.
Назначение: Удаление точки сохранения.
Доступно в: DSQL.
Синтаксис:
RELEASE SAVEPOINT sp_name
[ONLY]
Параметры оператора RELEASE SAVEPOINT
sp_name
Имя точки сохранения.
Оператор RELEASE SAVEPOINT удаляет именованную точку сохранения, освобождая все связанные с ней ресурсы. По умолчанию удаляются также все точки сохранения, создаваемые после указанной. Если указано предложение ONLY, то удаляется только точка сохранения с заданным именем.
См. также: SAVEPOINT.
По умолчанию сервер использует автоматическую системную точку сохранения уровня транзакции для выполнения её отката. При выполнении оператора ROLLBACK, все изменения, выполненные в транзакции, откатываются до системной точки сохранения и после этого транзакция подтверждается.
Когда объем изменений, выполняемых под системной точкой сохранения уровня транзакции, становится большим (затрагивается порядка 50000 записей) сервер освобождает системную точку сохранения и, при необходимости отката транзакции, использует механизм TIP.
Если вы ожидаете, что объем изменений в транзакции будет большим, то можно задать опцию NO AUTO UNDO в операторе SET TRANSACTION, или – если используется API – установить флаг TPB isc_tpb_no_auto_undo. В обеих вариантах предотвращается создание системной точки сохранения уровня транзакции.
Использование операторов управления транзакциями в PSQL не разрешается, так как это нарушит атомарность оператора, вызывающего процедуру. Но Firebird поддерживает вызов и обработку исключений в PSQL, так, чтобы действия, выполняемые в хранимых процедурах и триггерах, могли быть выборочно отменены без полного отката всех действий в них. Внутренне автоматические точки сохранения используется для:
отмены всех действий внутри блока BEGIN ... END, где происходит исключение;
отмены всех действий, выполняемых в хранимой процедуре/триггере (или, в случае селективной хранимой процедуры, всех действий, выполненных с момента последнего оператора SUSPEND), если они завершаются преждевременно из-за непредусмотренной ошибки или исключения.
Каждый блок обработки исключений PSQL также ограничен автоматическими точками сохранения сервера.
Сами по себе блок BEGIN..END не создаёт автоматическую точку сохранения. Она создаётся только в блоках, которых присутствует блок WHEN для обработки исключений или ошибок.
Базы данных, как и данные, хранимые в файлах базы данных, должны быть защищены. Firebird обеспечивает двухуровневую защиту данных — аутентификация пользователя на уровне сервера и привилегии на уровне базы данных. В данной главе рассказывается, каким образом управлять безопасностью вашей базы данных на каждом из уровней.
Безопасность всей базы данных зависит от проверки подлинности идентификатора
пользователя. Информация о пользователях, зарегистрированных для конкретного сервера
Firebird, хранится в особой базе данных безопасности (security database) —
security2.fdb
.
Имя пользователя может состоять максимум из 31 символа, при этом их регистр не учитывается. Пароль может состоять максимум из 8 символов (если ввести больше, лишние символы игнорируются), регистр — учитывается.
Встроенная версия сервера (embedded), не использует аутентификацию. Тем не менее, имя пользователя, и если необходимо роль, должны быть указаны в параметрах подключения, поскольку они используются для контроля доступа к объектам базы данных.
Пользователь SYSDBA или пользователь вошедший с ролью RDB$ADMIN, получают неограниченный доступ к базе данных. Если пользователь является владельцем базы данных, то без указания роли RDB$ADMIN он получает неограниченный доступ ко всем объектам принадлежащим этой базе данных.
В Firebird существует специальная учётная запись SYSDBA, которая существует вне всех ограничений безопасности и имеет полный доступ ко всем базам данных сервера. По умолчанию пароль SYSDBA — masterkey (точнее masterke, т.к. длина пароля ограничена 8 символами).
Пароль по умолчанию masterkey известен всем. Он должен быть изменён сразу после завершения установки Firebird.
В POSIX системах, включая MacOSX, имя пользователя POSIX будет интерпретировано как имя пользователя Firebird Embedded, если имя пользователя не указано явно.
В POSIX системах, кроме MacOSX, пользователь SYSDBA не имеет пароля по умолчанию. Если полная установка
установка осуществляется с помощью стандартных скриптов, то одноразовый
пароль будет создан и сохранён в текстовом файле в том же каталоге что и
security2.fdb
, обычно это
/opt/firebird/
. Файл с паролём имеет имя
SYSDBA.password
.
При выполнении установки с помощью определённого распространяемого установщика, расположение файла базы данных безопасности и файла с паролем может отличаться от стандартного.
В операционных системах семейства Windows NT вы также можете пользоваться
учётными записями ОС. Для этого необходимо включить разрешение на использование
доверительной аутентификации (Trusted Authentication). Для этого необходимо
установить параметр Authentication
в файле
конфигурации firebird.conf
в значение Trusted или
Mixed.
Администраторы операционной системы Windows автоматически не получают права SYSDBA при подключении к базе данных (если, конечно, разрешена доверенная авторизация). Имеют ли администраторы автоматические права SYSDBA, зависит от установки значения флага AUTO ADMIN MAPPING.
Владелец базы данных — это либо текущий пользователь (CURRENT_USER), который был момент создания, либо пользователь который был указан в параметрах USER и PASSWORD в операторе CREATE DATABASE.
Владелец базы данных является администратором в ней и имеет полный доступ ко всем объектам этой базы данных, даже созданных другими пользователями.
Системная роль RDB$ADMIN, присутствует в каждой базе данных. Предоставление пользователю роли RDB$ADMIN в базе данных даёт ему права SYSDBA, но только в текущей базе данных.
Привилегии вступают в силу сразу после входа в обычную базу данных с указанием роли RDB$ADMIN, после чего пользователь получает полный контроль над всеми объектами базы данных.
Предоставление в базе данных безопасности даёт возможность создавать, изменять и удалять учётные записи пользователей.
В обоих случаях пользователь с правами RDB$ADMIN роли может всегда передавать эту роль другим. Другими словами, «WITH ADMIN OPTION» уже встроен в эту роль и эту опцию можно не указывать.
Для предоставления и удаления роли RDB$ADMIN в обычной базе данных используются операторы GRANT и REVOKE, как и для назначения и отмены остальных ролей.
Синтаксис:
GRANT RDB$ADMIN TOusername
REVOKE RDB$ADMIN FROMusername
Таблица 9.1. Параметры операторов установки и отмены роли RDB$ADMIN
Параметр | Описание |
---|---|
username |
Имя пользователя, которому назначается роль RDB$ADMIN или у которого она отбирается. |
Привилегии на роль RDB$ADMIN могут давать только администраторы.
Так как никто не может соединиться с базой данных пользователей, то операторы GRANT и REVOKE здесь не могут использоваться. Вместо этого роль RDB$ADMIN предоставляют и удаляют SQL командами управления пользователями: CREATE USER и ALTER USER, в которых указываются специальные опции GRANT ADMIN ROLE и REVOKE ADMIN ROLE.
Синтаксис (неполный):
CREATE USERnewuser
PASSWORD 'password
' GRANT ADMIN ROLE ALTER USERexistinguser
GRANT ADMIN ROLE ALTER USERexistinguser
REVOKE ADMIN ROLE
Таблица 9.2. Параметры операторов установки и отмены роли RDB$ADMIN
Параметр | Описание |
---|---|
newuser |
Имя вновь создаваемого пользователя. Максимальная длина 31 символ. |
existinguser |
Имя существующего пользователя. |
password |
Пароль пользователя. Чувствительно к регистру. |
Пожалуйста, помните, что GRANT ADMIN ROLE и REVOKE ADMIN ROLE это не операторы GRANT и REVOKE. Это параметры для CREATE USER и ALTER USER.
Привилегии на роль RDB$ADMIN могут давать только администраторы.
См. также: CREATE USER, ALTER USER.
То же самое можно сделать используя утилиту
gsec указав параметр
-admin
для сохранения атрибута
RDB$ADMIN учётной записи пользователя:
gsec -add new_user -pw password -admin yes gsec -mo existing_user -admin yes gsec -mo existing_user -admin no
В зависимости от административного статуса текущего пользователя
для утилиты gsec может потребоваться
больше параметров, таких как -user
и
-pass
, или
-trusted
.
Для управления учётными записями пользователей через SQL пользователь, имеющий права на роль RDB$ADMIN, должен подключиться к базе данных с этой ролью. Так как к базе данных пользователей не имеет права соединяться никто, то пользователь должен подключиться к обычной базе данных, где он также имеет права на роль RDB$ADMIN. Он определяет роль при соединении с обычной базой данных и может в ней выполнить любой SQL запрос. Это не самое элегантное решение, но это единственный способ управлять пользователями через SQL запросы.
Если нет обычной базы данных, где у пользователя есть права на роль RDB$ADMIN, то управление учётными записями посредством SQL запросов недоступно.
Операционная система: только Windows.
Администраторы операционной системы Windows автоматически не получают права SYSDBA при подключении к базе данных (если, конечно, разрешена доверенная авторизация). Имеют ли администраторы автоматические права SYSDBA зависит от установки значения флага AUTO ADMIN MAPPING. Это флаг в каждой из баз данных, который по умолчанию выключен. Если флаг AUTO ADMIN MAPPING включен, то он действует, когда администратор Windows:
подключается с помощью доверенной аутентификации
не определяет никакой роли при подключении.
После успешного “auto admin” подключения текущей ролью будет являться RDB$ADMIN.
Включение и выключение флага AUTO ADMIN MAPPING в обычной базе данных осуществляется следующим образом:
ALTER ROLE RDB$ADMIN SET AUTO ADMIN MAPPING -- включение ALTER ROLE RDB$ADMIN DROP AUTO ADMIN MAPPING -- выключение
Эти операторы могут быть выполнены пользователями с достаточными правами, а именно:
владелец базы данных;
В обычных базах данных статус AUTO ADMIN MAPPING проверяется только во время подключения. Если Администратор имеет роль RDB$ADMIN потому, что произошло автоматическое отображение во время входа, то он будет удерживать эту роль на протяжении всей сессии, даже если он или кто-то другой в это же время выключает автоматическое отображение.
Точно также, включение AUTO ADMIN MAPPING не изменит текущую роль в RDB$ADMIN для Администраторов, которые уже подключились.
Нет никаких операторов SQL, чтобы включить или выключить флаг AUTO ADMIN MAPPING в базе данных пользователей. Для этого можно использовать только утилиту командной строки gsec:
gsec -mapping set gsec -mapping drop
В зависимости от административного статуса текущего пользователя
для утилиты gsec может потребоваться
больше параметров, таких как -user
и
-pass
, или
-trusted
.
Только SYSDBA может включить AUTO ADMIN MAPPING, если он выключен, но любой администратор может выключить его.
При выключении AUTO ADMIN MAPPING пользователь отключает сам механизм, который предоставлял ему доступ и, таким образом, он не сможет обратно включить AUTO ADMIN MAPPING. Даже в интерактивном gsec сеансе новая установка флага сразу вступает в силу.
Администратор — это пользователь, которые имеет достаточные права для чтения и записи, создания, изменения и удаления любого объекта в базе данных. В таблице показано, как привилегии «Суперпользователя» включены в различных контекстах безопасности Firebird.
Таблица 9.3. Администраторы
Пользователь | Роль RDB$ADMIN | Замечание |
---|---|---|
SYSDBA | Автоматически | Существует автоматически на уровне сервера. Имеет полные привилегии ко всем объектам во всех базах данных. Может создавать. изменять и удалять пользователей, но не имеет прямого доступа к базе данных безопасности. |
Пользователь root в POSIX | Автоматически | Также как SYSDBA. Только в Firebird Embedded. |
Суперпользователь в POSIX | Автоматически | Также как SYSDBA. Только в Firebird Embedded. |
Владелец базы данных | Автоматически | Также как SYSDBA, но только в этой базе данных. |
Администраторы Windows | Устанавливается в CURRENT_ROLE, если вход успешен |
Также как SYSDBA, если соблюдены следующие условия:
|
Обычный пользователь | Должна быть предварительно выдана и должна быть указана при входе | Также как SYSDBA, но только в тех базах данных, где эта роль предоставлена. |
Пользователь POSIX | Должна быть предварительно выдана и должна быть указана при входе | Также как SYSDBA, но только в тех базах данных, где эта роль предоставлена. Только в Firebird Embedded. |
Пользователь Windows | Должна быть предварительно выдана и должна быть указана при входе | Также как SYSDBA, но только в тех базах данных, где эта роль
предоставлена. Не доступно, если параметр конфигурации
Authentication имеет значение
native.
|
В данном разделе описываются операторы создания, модификации и удаления учётных записей пользователей Firebird средствами операторов SQL. Такая возможность предоставлена следующим пользователям обладающие полными административными привилегиями в базе данных безопасности.
Для Администраторов Windows, включение AUTO ADMIN MAPPING в обычной базе данных безопасности не является достаточным условием для обеспечения возможности управлять другими пользователями. Инструкции по его включению в базе данных безопасности см. Включение AUTO ADMIN MAPPING в базе данных безопасности
Непривилегированные пользователи могут использовать только оператор ALTER USER для изменения собственной учётной записи.
Назначение: Создание учётной записи пользователя Firebird.
Доступно в: DSQL.
Синтаксис:
CREATE USERusername
PASSWORD 'password
' [FIRSTNAME 'firstname
'] [MIDDLENAME 'middlename
'] [LASTNAME 'lastname
'] [GRANT ADMIN ROLE];<tag>
::=tagname
= 'string value
'
Таблица 9.4. Параметры оператора CREATE USER
Параметр | Описание |
---|---|
username |
Имя пользователя. Максимальная длина 31 символ. |
password |
Пароль пользователя. Может включать в себя до 31 символов, однако только первые 8 имеют значение. Чувствительно к регистру. |
firstname |
Вспомогательная информация: имя пользователя. Максимальная длина 32 символа. |
middlename |
Вспомогательная информация: "второе имя" (отчество, "имя отца") пользователя. Максимальная длина 32 символа. |
lastname |
Вспомогательная информация: фамилия пользователя. Максимальная длина 32 символа. |
Оператор CREATE USER создаёт учётную запись пользователя Firebird. Пользователь должен отсутствовать в базе данных безопасности Firebird иначе будет выдано соответствующее сообщение об ошибке.
Параметр username
должен соответствовать правилам для
идентификаторов Firebird (см. Идентификаторы). Имена пользователей всегда нечувствительны к регистру.
Указание имени пользователя в двойных кавычках не вызовут ошибку: кавычки будут
проигнорированы. Если пробел будет единственным недопустимым символом, то имя
пользователя будет усечено до первого пробела. Другие недопустимые символы вызовут
исключение.
Предложение PASSWORD задаёт пароль пользователя. Пароль более восьми символов допустим, но вызовет предупреждение, лишние символы будут проигнорированы.
Необязательные предложения FIRSTNAME, MIDDLENAME и LASTNAME задают дополнительные атрибуты пользователя, такие как имя пользователя (имя человека), отчество и фамилия соответственно.
Если указана опция GRANT ADMIN ROLE, то новая учётная запись пользователя
создаётся с правами роли RDB$ADMIN в базе данных безопасности
(security2.fdb
). Это позволяет вновь созданному
пользователю управлять учётными записями пользователей, но не даёт ему специальных
полномочий в обычных базах данных.
Для создания учётной записи пользователя текущий пользователь должен обладать административными привилегиями в базе данных безопасности. Пользователи являющиеся администраторами только в обычной базе данных не могут создавать новые учётные записи.
Операторы CREATE/ALTER/DROP USER являются DDL операторами. Не забывайте подтверждать (COMMIT) вашу работу. В isql, команда SET AUTO ON позволяет включить автоматическое подтверждение транзакций для DDL операторов. В сторонних инструментах и пользовательских приложениях это может быть не так.
Примеры:
Пример 9.2. Создание пользователя John с дополнительными атрибутами (именем и фамилией).
CREATE USER john PASSWORD 'fYe_3Ksw' FIRSTNAME 'John' LASTNAME 'Doe';
Пример 9.3. Создание пользователя с возможностью управления пользователями.
CREATE USER superuser PASSWORD 'kMn8Kjh'
GRANT ADMIN ROLE;
См. также: ALTER USER, DROP USER.
Назначение: Изменение учётной записи пользователя Firebird.
Доступно в: DSQL.
Синтаксис:
ALTER USERusername
{ [SET] [PASSWORD 'password
'] [FIRSTNAME 'firstname
'] [MIDDLENAME 'middlename
'] [LASTNAME 'lastname
'] } [{GRANT | REVOKE} ADMIN ROLE];
Таблица 9.5. Параметры оператора ALTER USER
Параметр | Описание |
---|---|
username |
Имя пользователя. Не может быть изменено. |
password |
Пароль пользователя. Может включать в себя до 31 символов, однако только первые 8 имеют значение. Чувствительно к регистру. |
firstname |
Вспомогательная информация: имя пользователя. Максимальная длина 32 символа. |
middlename |
Вспомогательная информация: "второе имя" (отчество, "имя отца") пользователя. Максимальная длина 32 символа. |
lastname |
Вспомогательная информация: фамилия пользователя. Максимальная длина 32 символа. |
Оператор ALTER USER изменяет данные учётной записи пользователя. Для модификации чужой учётной записи пользователя текущий пользователь должен обладать административными привилегиями в базе данных безопасности. Пользователи являющиеся администраторами только в обычной базе данных не могут изменять чужие учётные записи.
Свои собственные учётные записи могут изменять любые пользователи, однако это не относится к опциям GRANT/REVOKE ADMIN ROLE для изменения которых, необходимы административные привилегии.
Все аргументы за исключением имени пользователя в операторе ALTER USER являются необязательными, но хотя бы один из них должен присутствовать.
Необязательное предложение PASSWORD задаёт новый пароль пользователя.
Необязательные предложения FIRSTNAME, MIDDLENAME и LASTNAME позволяют изменить дополнительные атрибуты пользователя, такие как имя пользователя (имя человека), отчество и фамилия соответственно.
Предложение GRANT ADMIN ROLE предоставляет указанному пользователю привилегии роли
RDB$ADMIN в базе данных безопасности (security2.fdb
). Это
позволяет указанному пользователю управлять учётными записями пользователей, но не
даёт ему специальных полномочий в обычных базах данных.
Предложение REVOKE ADMIN ROLE отбирает у указанного пользователя привилегии роли RDB$ADMIN в текущей базе данных безопасности. Это запрещает указанному пользователю управлять учётными записями пользователей.
Не забывайте подтверждать свою работу, если вы работаете в приложении не поддерживающим автоматическое подтверждение транзакций для DDL операторов.
Примеры:
Пример 9.4. Изменение пользователя и выдача ему привилегии управления пользователями.
ALTER USER bobby PASSWORD '67-UiT_G8'
GRANT ADMIN ROLE;
Пример 9.5. Изменение дополнительных атрибутов своей учётной записи.
ALTER CURRENT USER FIRSTNAME 'No_Jack' LASTNAME 'Kennedy';
Пример 9.6. Отбор привилегии управления пользователями у пользователя.
ALTER USER dumbbell REVOKE ADMIN ROLE;
См. также: CREATE USER, DROP USER.
Назначение: Удаление учётной записи пользователя Firebird.
Доступно в: DSQL.
Синтаксис:
DROP USER username
;
Оператор DROP USER удаляет учётную запись пользователя Firebird.
Для удаления учётной записи пользователя текущий пользователь должен обладать административными привилегиями в базе данных безопасности. Пользователи являющиеся администраторами только в обычной базе данных не могут удалять учётные записи.
Не забывайте подтверждать свою работу, если вы работаете в приложении не поддерживающим автоматическое подтверждение транзакций для DDL операторов.
Примеры:
См. также: CREATE USER, ALTER USER.
Роль (role) — объект базы данных, представляющий набор привилегий. Роли реализуют концепцию управления безопасностью на групповом уровне. Множество привилегий предоставляется роли, а затем роль может быть предоставлена или отозвана у одного или нескольких пользователей.
Пользователь, которому предоставлена роль, должен указать её при входе, для того чтобы получить её привилегии. Любые другие привилегии, предоставленные пользователю, не будут затронуты при его входе в систему с указанной ролью. Вход в систему с несколькими ролями не поддерживается.
В данном разделе рассматриваются вопросы создания и удаления ролей.
Назначение: Создание новой роли.
Доступно в: DSQL, ESQL.
Синтаксис:
CREATE ROLE rolename
;
Таблица 9.7. Параметры оператора CREATE ROLE
Параметр | Описание |
---|---|
rolename |
Имя роли. Максимальная длина 31 символ. |
Оператор CREATE ROLE создаёт новую роль. Имя роли должно быть уникальным среди имён ролей.
Желательно также чтобы имя роли было уникальным не только среди имён ролей, но и среди имён пользователей. Если вы создадите роль с тем же именем существующего пользователя, то такой пользователь не сможет подключиться к базе данных.
Создать роль может любой пользователь, подключенный к базе данных. Пользователь, создавший роль, становится её владельцем.
Примеры:
Оператору ALTER ROLE нет места в парадигме create-alter-drop как для других объектов базы данных, так как у роли нет атрибутов, которые могут быть изменены. Этот оператор применяется для изменения одного из атрибутов базы данных. В Firebird он используется для включения и отключения возможности администраторам Windows автоматически предоставлять привилегии администраторов при входе.
Эта возможность существует только для одной роли, а именно системной роли RDB$ADMIN, которая существует в любой базе данных с ODS 11.2 и выше.
Подробности см. в AUTO ADMIN MAPPING главы Безопасность.
Назначение: Удаление существующей роли.
Доступно в: DSQL, ESQL.
Синтаксис:
DROP ROLE rolename
;
Оператор DROP ROLE удаляет существующую роль. При удалении роли все привилегии, предоставленные этой роли, отменяются.
Роль может быть удалена владельцем или администраторами.
Примеры:
См. также: CREATE ROLE, GRANT, REVOKE.
Вторым уровень модели обеспечения безопасности Firebird являются SQL привилегии. После успешного входа в систему (первый уровень), авторизованный пользователь получает доступ к серверу и ко всем базам данных этого сервера, но это не означает, что он имеет доступ к любым объектам в любой базе данных. После создания объекта, только пользователь создавший объект (его владелец) и администраторы имеют доступ к нему. Пользователю необходимы привилегии на каждый объект, к которому он должен получить доступ. Как правило, привилегии должны быть предоставлены явно пользователю владельцем объекта или администратором базы данных.
Привилегия включает тип DML доступа (SELECT, INSERT, UPDATE, DELETE, EXECUTE и REFERENCES), имя объекта базы данных для которого предоставляется привилегия (таблица, представление, процедура или роль) и имя объекта которому предоставляется привилегия (пользователь, процедура, триггер, роль). Существуют различные способы для предоставления нескольких типов доступа на один объект базы данных сразу нескольким пользователям в одном операторе GRANT. Привилегии могут быть отозваны с помощью оператора REVOKE.
Все привилегии по доступу к объектам базы данных хранятся в самой базе, и не могут быть применены к любой другой базе данных.
Пользователь, создавший объект базы данных, становится его владельцем. Только владелец объекта и пользователи с правами администратора в базе данных могут изменить или удалить объект базы данных. Владелец базы данных, то есть пользователь, который создал её, имеет все права на объекты, которые были созданы другими пользователями.
К сожалению, вопросы создания новых объектов базы данных не контролируются в настоящий момент (Firebird 2.5). Любой авторизованный пользователь, имеющий доступ к базе данных, может создать любой допустимый объект базы данных.
Кроме того, не все объекты базы данных ассоциированы с владельцем, что делает их уязвимыми (позволяет изменять и удалять любым пользователям). Это относится к доменам, функциям (UDF), BLOB фильтрам, генераторам (последовательностям) и исключениям.
Администраторы или владелец объекта могут выдавать привилегии другим пользователям, в том числе и привилегии на право выдачи привилегий другим пользователям. Собственно сам процесс раздачи и отзыва привилегий на уровне SQL реализуется двумя операторами: GRANT, REVOKE.
Назначение: Предоставление привилегий или назначение ролей.
Доступно в: DSQL.
Синтаксис:
<grant_stmt>
::=<grant_priv_stmt>
|<grant_roles_stmt>
<grant_priv_stmt>
::= GRANT {<privileges>
ON [TABLE] {tablename
|viewname
} | EXECUTE ON PROCEDUREprocname
} TO<grantee_list>
[WITH GRANT OPTION] [{GRANTED BY | AS} [USER]grantor
]<grant_roles_stmt>
::= GRANT<role_granted>
TO<role_grantee_list>
[WITH ADMIN OPTION] [{GRANTED BY | AS} [USER]grantor
]<privileges>
::= ALL [PRIVILEGES] |<privilege_list>
<privilege_list>
::= {<privilege>
[,<privilege>
[, ...] ] }<privilege_list>
::= SELECT | DELETE | INSERT | UPDATE [(col
[,col
[, ...] ])] | REFERENCES (col
[,col
[, ...] ])<grantee_list>
::= {<grantee>
[,<grantee>
[, ...] ] }<grantee>
::= [USER]username
| [ROLE]rolename
| GROUPUnix_group
| PROCEDUREprocname
| TRIGGERtrigname
| VIEWviewname
| PUBLIC<role_granted>
::=rolename
[,rolename
...]<role_grantee_list>
::=<role_grantee>
[,<role_grantee>
[, ...] ]<role_grantee>
::= { [USER]username
| PUBLIC }
Таблица 9.9. Параметры оператора GRANT
Параметр | Описание |
---|---|
tablename |
Имя таблицы, к которой должно быть применена привилегия. |
viewname |
Имя представления, к которому должно быть применена привилегия или которому будут выданы привилегии. |
procname |
Имя хранимой процедуры, для которой должна быть выдана привилегия EXECUTE или которой будут даны привилегии. |
trigname |
Имя триггера, которому будут даны привилегии. |
col |
Столбец таблицы, к которому должна быть применена привилегия. |
username |
Имя пользователя, для которого выдаются привилегии или которому назначается роль. |
rolename |
Имя роли. |
Unix_group |
Имя группы пользователей в операционных системах семейства UNIX. Только в Firebird Embedded. |
grantor |
Пользователь от имени, которого предоставляются привилегии. |
Оператор GRANT предоставляет одну или несколько привилегий для объектов базы данных пользователям, ролям, хранимым процедурам, функциям, пакетам, триггерам и представлениям.
Авторизованный пользователь не имеет никаких привилегий до тех пор, пока какие либо права не будут предоставлены ему явно. При создании объекта только его создатель и администраторы имеют привилегии на него и могут назначать привилегии другим пользователям, ролям или объектам.
Для различных типов объектов метаданных существует различный набор привилегий. Эти привилегии будут описаны далее отдельно для каждого из типов объектов метаданных.
В предложении TO указывается список пользователей, ролей и объектов базы данных (процедур, триггеров и представлений) для которых будут выданы перечисленные привилегии. Это предложение является обязательным.
Необязательные предложения USER и ROLE позволяют уточнить, кому именно выдаётся привилегия. Если ключевое слово USER или ROLE не указано, то сервер проверяет, существует ли роль с данным именем, если таковой не существует, то привилегии назначаются пользователю.
Роль представляет собой объект «контейнер», который может быть использован для упаковки набора привилегий. Для использования роли необходимо предоставить её каждому пользователю, которому требуются эти привилегии. Роль также может быть предоставлена списку пользователей.
Роль должна существовать перед предоставлением ей привилегий. Синтаксис создания роли можно посмотреть в разделе CREATE ROLE главы DDL. Роль сохраняет предоставленные ей привилегии. При необходимости эти привилегии можно забрать у неё. При удалении роли (см. DROP ROLE) все пользователи теряют привилегии получаемые через эту роль. Любые привилегии, которые были предоставлены затронутому пользователю дополнительно через различные операторы GRANT, сохраняются.
Пользователь, которому предоставляется роль, должен указать эту роль вместе со своими учётными данными при входе в систему, для того чтобы получить её привилегии. Любые другие привилегии, предоставленные пользователю, не будут затронуты при входе в систему с указанием роли.
Одному пользователю может быть предоставлено более одной роли, но вход в систему с множеством ролей не поддерживается.
Роль может быть предоставлена только пользователю.
При выполнении оператора GRANT существование пользователя грантополучателя не проверяется в базе данных. Это не является ошибкой: SQL привилегии осуществляют контроль доступа для всех аутентифицированных пользователей, как обычных, так и доверенных. Доверенные пользователи операционной системы не могут быть сохранены в базе данных безопасности.
Если привилегия выдаётся объекту базы данных, то необходимо обязательно указывать тип объекта между ключевым словом TO и именем объекта.
Несмотря на то, что ключевые слова USER и ROLE не обязательные, желательно использовать их, чтобы избежать двусмысленности.
В SQL существует специальный пользователь PUBLIC, представляющий всех пользователей. Если какая-то операция разрешена пользователю PUBLIC, значит, любой аутентифицированный пользователь может выполнить эту операцию над указанным объектом.
Если привилегии назначены пользователю PUBLIC, то и отозваны они должны быть у пользователя PUBLIC.
Необязательное предложение WITH GRANT OPTION позволяет пользователям, указанным в списке пользователей, передавать другим пользователям привилегии указанные в списке привилегий.
При предоставлении прав в базе данных в качестве лица, предоставившего эти права, обычно записывается текущий пользователь. Используя предложение GRANTED BY можно предоставлять права от имени другого пользователя.
При использовании оператора REVOKE после GRANTED BY права будут удалены только в том случае, если они были зарегистрированы от удаляющего пользователя.
Для облегчения миграции из некоторых других реляционных СУБД нестандартное предложение AS поддерживается как синоним оператора GRANTED BY.
Предложения GRANTED BY и AS могут использовать только владелец базы данных и администраторы. Даже владелец объекта не может использовать их, если он не имеет административных привилегий.
Для таблиц и представлений в отличие от других объектов метаданных возможно использовании сразу нескольких привилегий.
Список привилегий для таблиц
Разрешает выборку данных из таблицы или представления.
Разрешает добавлять записи в таблицу или представление.
Разрешает изменять записи в таблице или представлении. Можно указать ограничения, чтобы можно было изменять только указанные столбцы.
Разрешает удалять записи из таблицы или представления.
Разрешает ссылаться на указанные столбцы внешним ключом. Необходимо указать для столбцов, на которых построен первичный ключ таблицы, если на неё есть ссылка внешним ключом другой таблицы.
Объединяет привилегии SELECT, INSERT, UPDATE, DELETE и REFERENCES.
Примеры:
Пример 9.10. Назначение привилегий для таблиц
-- Привилегии SELECT, INSERT пользователю ALEX GRANT SELECT, INSERT ON TABLE SALES TO USER ALEX; -- Привилегия SELECT ролям MANAGER, ENGINEER и пользователю IVAN GRANT SELECT ON TABLE CUSTOMER TO ROLE MANAGER, ROLE ENGINEER, USER IVAN; -- Все привилегии для роли ADMINISTRATOR -- с возможностью передачи своих полномочий GRANT ALL ON TABLE CUSTOMER TO ROLE ADMINISTRATOR WITH GRANT OPTION; -- Привилегии SELECT и REFRENCE для столбца NAME для всех пользователей GRANT SELECT, REFERENCES (NAME) ON TABLE COUNTRY TO PUBLIC; -- Выдача привилегии SELECT для пользователя IVAN от имени пользователя ALEX GRANT SELECT ON TABLE EMPLOYEE TO USER IVAN GRANTED BY ALEX; -- Привилегия UPDATE для столбцов FIRST_NAME, LAST_NAME GRANT UPDATE (FIRST_NAME, LAST_NAME) ON TABLE EMPLOYEE TO USER IVAN; -- Привилегия INSERT для хранимой процедуры ADD_EMP_PROJ GRANT INSERT ON EMPLOYEE_PROJECT TO PROCEDURE ADD_EMP_PROJ;
Привилегия EXECUTE (выполнение) применима к хранимым процедурам.
Для хранимых процедур привилегия EXECUTE позволяет не только выполнять хранимые процедуры, но и делать выборку данных из селективных процедур (с помощью оператора SELECT).
Примеры:
Пример 9.11. Назначение привилегии EXECUTE
-- Привилегия EXECUTE для хранимой процедуры
GRANT EXECUTE ON PROCEDURE ADD_EMP_PROJ
TO ROLE MANAGER;
Оператор GRANT может быть использован для назначения ролей для группы перечисленных пользователей. В этом случае после предложения GRANT следует список ролей, которые будут назначены списку пользователей, указанному после предложения TO.
Необязательное предложение WITH ADMIN OPTION позволяет пользователям, указанным в списке пользователей, назначать роли из списка ролей, указанных в списке ролей, другим пользователям.
Примеры:
Пример 9.12. Назначение ролей для пользователей
-- Назначение ролей DIRECTOR и MANAGER пользователю IVAN GRANT DIRECTOR, MANAGER TO USER IVAN; -- Назначение роли ADMIN пользователю ALEX -- с возможностью назначить эту другим пользователям GRANT MANAGER TO USER ALEX WITH ADMIN OPTION;
См. также: REVOKE.
Назначение: Отмена привилегий или отбор ролей.
Доступно в: DSQL.
Синтаксис:
<revoke_stmt>
::=<revoke_priv_stmt>
|<revoke_role_stmt>
|<revoke_all_stmt>
<revoke_priv_stmt>
::= REVOKE [GRANT OPTION FOR] {<privileges>
ON [TABLE] {tablename
|viewname
} | EXECUTE ON PROCEDUREprocname
} FROM<grantee_list>
[{GRANTED BY | AS} [USER]grantor
]<revoke_role_stmt>
::= REVOKE [ADMIN OPTION FOR]<role_granted>
FROM {PUBLIC |<role_grantee_list>
} [{GRANTED BY | AS} [USER]grantor
]<revoke_all_stmt>
::= REVOKE ALL ON ALL FROM<grantee_list>
[{GRANTED BY | AS} [USER]grantor
] {<object_list>
| PUBLIC |<user_list>
}<privileges>
::= { ALL [PRIVILEGES] |<privileges_list>
}<privilege_list>
::= {<privilege>
[,<privilege>
[, ... ] ] }<privilege>
::= SELECT | DELETE | INSERT | UPDATE [(col
[,col
...])] | REFERENCES [(col
[,col
...])]<grantee_list>
::= {<grantee>
[,<grantee>
[, ... ] ] }<grantee>
::= { [USER]username
| [ROLE]rolename
| GROUPUnix_group
| PROCEDUREprocname
| TRIGGERtrigname
| VIEWviewname
| PUBLIC<role_granted>
::=rolename
[,rolename
...]<role_grantee_list>
::=<role_grantee>
[,<role_grantee>
[, ...] ]<role_grantee>
::= { [USER]username
| PUBLIC }
Таблица 9.10. Параметры оператора REVOKE
Параметр | Описание |
---|---|
tablename |
Имя таблицы, у которой должна быть отозвана привилегия. |
viewname |
Имя представления для которого должна быть отозваны привилегии или у которого будет отозваны привилегии. |
procname |
Имя хранимой процедуры, для которой должна быть отозвана привилегия EXECUTE или у которой должны быть отозваны привилегии. |
trigname |
Имя триггера. |
col |
Столбец таблицы, у которого должна быть отозвана привилегия. |
username |
Имя пользователя, для которого отзываются привилегии или роль. |
rolename |
Имя роли. |
Unix_group |
Имя группы пользователей в операционных системах семейства UNIX. Только в Firebird Embedded. |
grantor |
Пользователь от имени, которого отзываются привилегии. |
Оператор REVOKE отменяет привилегии у пользователей, ролей, хранимых процедур, триггеров и представлений выданные оператором GRANT. Подробное описание различных типов привилегий см. в GRANT.
Только пользователь, который назначил привилегию, может удалить её.
В предложении FROM указывается список пользователей, ролей и объектов базы данных (процедур, триггеров и представлений) у которых будут отняты перечисленные привилегии. Необязательные предложения USER и ROLE позволяют уточнить, у кого именно выдаётся привилегия. Если ключевое слово USER или ROLE не указано, то сервер проверяет, существует ли роль с данным именем, если таковой не существует, то привилегии отбираются у пользователя.
Несмотря на то, что ключевые слова USER и ROLE не обязательные, желательно использовать их, чтобы избежать неоднозначности.
Существование пользователя, у которого отбираются права, не проверяются при выполнении оператора REVOKE.
Если привилегия отбирается у объекта базы данных, то необходимо обязательно указывать тип объекта.
Если привилегии были назначены специальному пользователю PUBLIC, то отменять привилегии необходимо для пользователя PUBLIC. Специальный пользователь PUBLIC используется, когда необходимо предоставить привилегии сразу всем пользователям. Однако не следует рассматривать PUBLIC как группу пользователей.
Необязательное предложение GRANT OPTION FOR отменяет для соответствующего пользователя или роли право предоставления другим пользователям или ролям привилегии к таблицам, представлениям, триггерам, хранимым процедурам.
Другое назначение оператора REVOKE в отмене назначенных группе пользователей ролей оператором GRANT. В этом случае после предложения REVOKE следует список ролей, которые будут отозваны у списка пользователей, указанных после предложения FROM.
Необязательное предложение ADMIN OPTION FOR отменяет ранее предоставленную административную опцию (право на передачу предоставленной пользователю роли другим) из грантополучателей, не отменяя прав на роль.
В одном операторе могут быть обработаны несколько ролей и/или грантополучателей.
При предоставлении прав в базе данных в качестве лица, предоставившего эти права, обычно записывается текущий пользователь. Используя предложение GRANTED BY в операторе GRANT можно предоставлять права от имени другого пользователя. Чтобы отменить привилегии, назначенные таким образом, необходимо чтобы пользователь обладал полными административными привилегиями и грантодатель указан в предложении GRANTED BY оператора REVOKE.
Для облегчения миграции из некоторых других реляционных СУБД нестандартное предложение AS поддерживается как синоним оператора GRANTED BY.
Если вошел в систему в качестве администратора базе данных, то оператор
REVOKE ALL ON ALL FROM <grantee_list>
отменяет все привилегии (включая роли) на всех объектах от одного или более пользователей и/или ролей. Это быстрый способ «очистить» (отобрать) права, когда пользователю должен быть заблокирован доступ к базе данных.
Если текущий пользователь не вошел в систему в качестве администратора, то будут отменены только те привилегии, которые были предоставлены этого от этого пользователя.
Оператор REVOKE ALL ON ALL не может быть использован для отмены привилегий, которые были предоставлены хранимым процедурам, триггерам или представлениям.
Предложение GRANTED BY не поддерживается.
Примеры:
Пример 9.13. Отзыв привилегий на таблицу
-- отзыв привилегий SELECT, INSERT у таблицы REVOKE SELECT, INSERT ON TABLE SALES FROM USER ALEX -- отзыв привилегии SELECT у ролей MANAGER и ENGINEER и пользователя IVAN REVOKE SELECT ON TABLE CUSTOMER FROM ROLE MANAGER, ROLE ENGINEER, USER IVAN; -- отмена возможности передавать любую из привилегии на таблицу -- другим пользователям или ролям у роли ADMINISTRATOR REVOKE GRANT OPTION FOR ALL ON TABLE CUSTOMER FROM ROLE ADMINISTRATOR; -- отзыв привилегий SELECT и REFERENCES у пользователя PUBLIC REVOKE SELECT, REFERENCES (NAME) ON TABLE COUNTRY FROM PUBLIC; -- отзыв привилегии SELECT у пользователя IVAN, -- которая была выдана пользователем ALEX REVOKE SELECT ON TABLE EMPLOYEE FROM USER IVAN GRANTED BY ALEX; -- отзыв привилегии UPDATE для столбцов FIRST_NAME, LAST_NAME REVOKE UPDATE (FIRST_NAME, LAST_NAME) ON TABLE EMPLOYEE FROM USER IVAN; -- отзыв привилегии INSERT у хранимой процедуры ADD_EMP_PROJ REVOKE INSERT ON EMPLOYEE_PROJECT FROM PROCEDURE ADD_EMP_PROJ;
Пример 9.14. Отзыв привилегии EXECUTE
-- отзыв привилегии EXECUTE для процедуры
REVOKE EXECUTE ON PROCEDURE ADD_EMP_PROJ
FROM USER IVAN;
Пример 9.15. Отзыв ролей
-- Отзыв ролей DIRECTOR, MANAGER у пользователя IVAN REVOKE DIRECTOR, MANAGER FROM USER IVAN; -- Отзыв роли MANAGER и права назначать её другим пользователям REVOKE ADMIN OPTION FOR MANAGER FROM USER ALEX;
Пример 9.16. Отзыв всех привилегий и ролей у пользователя
REVOKE ALL ON ALL FROM IVAN;
После выполнения этой команды у пользователя IVAN нет вообще никаких прав.
См. также: GRANT.
В системных таблицах RDB$PROCEDURES и RDB$TRIGGERS присутствует поле RDB$VALID_BLR. Оно предназначено для сигнализации о возможной недействительности модуля PSQL (процедуры или триггера) после изменения доменов или столбцов таблиц, от которых он зависит. При возникновении описанной выше ситуации поле RDB$VALID_BLR устанавливается в 0 для процедур или триггеров, код которых возможно является недействительным.
В триггерах и процедурах зависимости возникают от столбцов таблицы к которой они обращаются, а так же от любого параметра или переменной которые определены в модуле с использованием предложения TYPE OF.
После того, как ядро Firebird изменило любой домен, включая неявные домены, создаваемые внутри при определении столбцов или параметров, Firebird производит внутреннюю перекомпиляцию всех зависимостей.
В Firebird 2.x инвалидация происходит для процедур и триггеров, но не для блоков DML операторов, которые выполняются при помощи EXECUTE BLOCK. Firebird 3 охватывает большое число типов модулей (хранимые функции и пакеты).
Любой модуль, который не удалось перекомпилировать из-за несовместимости, возникающей из-за изменения домена, помечается как недействительный (поле RDB$VALID_BLR устанавливается в 0 в записи соответствующей системной таблице (RDB$PROCEDURES или RDB$TRIGGERS).
Возобновление (установка RDB$VALID_BLR в 1) происходит когда
домен изменён снова и его новое определение совместимо с ранее недействительным определением модуля; или
ранее недействительный модуль изменён так, что соответствовать новому определению домена.
Нижеприведённый запрос находит процедуры и триггеры, зависящие от определённого домена (в примере это домен 'MYDOMAIN'), и выводит информацию о состоянии поля RDB$VALID_BLR:
SELECT * FROM ( SELECT 'Procedure', RDB$PROCEDURE_NAME, RDB$VALID_BLR FROM RDB$PROCEDURES UNION ALL SELECT 'Trigger', RDB$TRIGGER_NAME, RDB$VALID_BLR FROM RDB$TRIGGERS) (TYPE, NAME, VALID) WHERE EXISTS (SELECT * FROM RDB$DEPENDENCIES WHERE RDB$DEPENDENT_NAME = NAME AND RDB$DEPENDED_ON_NAME = 'MYDOMAIN') /* Замените MYDOMAIN фактическим именем проверяемого домена. Используйте заглавные буквы, если домен создавался нечувствительным к регистру — в противном случае используйте точное написание имени домена с учётом регистра */
Следующий запрос находит процедуры и триггеры, зависящие от определенного столбца таблицы (в примере это столбец 'MYCOLUMN' таблицы 'MYTABLE'), и выводит информацию о состоянии поля RDB$VALID_BLR:
SELECT * FROM ( SELECT 'Procedure', RDB$PROCEDURE_NAME, RDB$VALID_BLR FROM RDB$PROCEDURES UNION ALL SELECT 'Trigger', RDB$TRIGGER_NAME, RDB$VALID_BLR FROM RDB$TRIGGERS) (TYPE, NAME, VALID) WHERE EXISTS (SELECT * FROM RDB$DEPENDENCIES WHERE RDB$DEPENDENT_NAME = NAME AND RDB$DEPENDED_ON_NAME = 'MYTABLE' AND RDB$FIELD_NAME = 'MYCOLUMN') /* Замените MYTABLE и MYCOLUMN фактическими именами проверяемой таблицы и её столбца. Используйте заглавные буквы, если таблица и её столбец создавались нечувствительными к регистру — в противном случае используйте точное написание имени таблицы и её столбца с учётом регистра */
Все случаи возникновения недействительных модулей, вызванных изменениями доменов/столбцов, отражаются в поле RDB$VALID_BLR. Тем не менее, другие виды изменения, таких как изменения количества входных или выходных параметров процедур и так далее, не влияют на поле проверки, даже если потенциально они могут привести к недействительности модуля. Типичные сценарии могут быть следующими:
Процедура (B) определена так, что она вызывает другую процедуру (A) и считывает выходные параметры из неё. В этом случае зависимость будет зарегистрирована в RDB$DEPENDENCIES. В последствии вызываемая процедура (A) может быть изменена для изменения или удаления одного и более выходных параметров. Оператор ALTER PROCEDURE A приведёт к ошибки при выполнении фиксации транзакции.
Процедура (B) вызывает процедуру (A), передавая ей значения в качестве входных параметров. Никаких зависимостей не будет зарегистрировано в RDB$DEPENDENCIES. Последующие модификации входных параметров процедуры A будут позволены. Отказ произойдет во время выполнения, когда В вызовет A с несогласованным набором входных параметров.
Для модулей PSQL, наследованных от более ранних версий Firebird (включая многие системные триггеры, даже если база данных создавалась под версией Firebird 2.1 или выше), поле RDB$VALID_BLR имеет значение NULL. Это не означает, что их BLR является недействительным.
Команды утилиты командной строки isql SHOW PROCEDURES и SHOW TRIGGERS при выводе информации отмечают звёздочкой модули, у которых поле RDB$VALID_BLR равно 0. Команды SHOW PROCEDURE <procname> и SHOW TRIGGER <trigname>, выводящие на экран код PSQL модуля, не сигнализируют пользователя о недопустимом BLR.
Это замечание об операторах равенства и неравенства применяется повсюду в СУБД Firebird.
Оператор "=", который используется во многих условиях, сравнивает только значения со значениями. В соответствии со стандартом SQL, NULL не является значением и, следовательно, два значения NULL не равны и ни неравны друг с другом. Если необходимо, чтобы значения NULL соответствовали друг другу при объединении, используйте оператор IS NOT DISTINCT FROM. Этот оператор возвращает истину, если операнды имеют то же значение, или, если оба они равны NULL.
SELECT * FROM A JOIN B ON A.id IS NOT DISTINCT FROM B.code
Точно так же, если вы хотите чтобы значения NULL отличались от любого значения и два значения NULL считались равными, используйте оператор IS DISTINCT FROM вместо оператора "<>".
SELECT * FROM A JOIN B ON A.id IS DISTINCT FROM B.code
Приложение включает:
В Firebird DDL существует простой синтаксис для создания пользовательских исключений для использования в PSQL, с текстами сообщений до 1021 символов. Подробности см. CREATE EXCEPTION главы DDL. Подробности использования пользовательских исключений см. EXCEPTION главы PSQL.
В большинстве случаев, коды ошибок SQLCODE не соотносятся с кодами SQLSTATE "один в один". Коды ошибок SQLSTATE соответствуют SQL стандарту. В то же время SQLCODE использовались много лет и в настоящий момент считаются устаревшими. В следующих вервиях поддержка SQLCODE может полностью прекратиться.
В данной главе приведены коды ошибок для контекстной переменной SQLSTATE и их описания. Коды ошибок SQLSTATE построены следующим образом: пяти символьный код ошибки состоит и SQL класса ошибки (2 символа) и SQL подкласса (3 символа).
Таблица B.1. Коды ошибок SQLSTATE
Код SQLSTATE | Связанное сообщение | Примечание |
---|---|---|
SQLCLASS 00 (Success) | ||
0 | Success | Успех |
SQLCLASS 01 (Warning) | Класс 01 (предупреждения) | |
01000 | General Warning | Общее предупреждение |
01001 | Cursor operation conflict | Конфликт при операции с курсором |
01002 | Disconnect error | Ошибка, связанная с разъединением |
01003 | NULL value eliminated in set function | Значение NULL устраняется в определении функции |
01004 | String data, right-truncated | Строковые данные, обрезание справа |
01005 | Insufficient item descriptor areas | Недостаточно элементов в области дескрипторов |
01006 | Privilege not revoked | Привилегии не отозваны |
01007 | Privilege not granted | Привилегии не выданы |
01008 | Implicit zero-bit padding | Неявное обрезание нулевого бита |
01100 | Statement reset to unprepared | Оператор сброшен в состояние unprepared |
01101 | Ongoing transaction has been committed | Текущая транзакция завершена COMMIT |
01102 | Ongoing transaction has been rolled back | Текущая транзакция завершена ROLLED BACK |
SQLCLASS 02 (No Data) | Класс ошибок 02 (Нет данных) | |
02000 | No data found or no rows affected | Данные не обнаружены или не затронуты строки |
SQLCLASS 07 (Dynamic SQL error) | Класс ошибок 07 (Ошибки DSQL) | |
07000 | Dynamic SQL error | Ошибка DSQL |
07001 | Wrong number of input parameters | Неверное число входных параметров |
07002 | Wrong number of output parameters | Неверное число выходных параметров |
07003 | Cursor specification cannot be executed | Определение курсора не может быть выполнено |
07004 | USING clause required for dynamic parameters | Для динамического параметра требуется предложение USING |
07005 | Prepared statement not a cursor-specification | Подготовленный оператор не является курсор - специфичным |
07006 | Restricted data type attribute violation | Исключение по причине запрещенного типа данных для атрибута |
07007 | USING clause required for result fields | Для возвращаемого поля требуется предложение USING |
07008 | Invalid descriptor count | Неверный счетчик дескрипторов |
07009 | Invalid descriptor index | Неверный индекс дескриптора |
SQLCLASS 08 (Connection Exception) | Класс ошибок 08 (Исключения коннекта) | |
08001 | Client unable to establish connection | Клиент не может установить соединение |
08002 | Connection name in use | Имя соединения уже используется |
08003 | Connection does not exist | Соединение не существует |
08004 | Server rejected the connection | Сервер отверг подключение |
08006 | Connection failure | Ошибка при подключении |
08007 | Transaction resolution unknown | Неизвестно разрешение транзакции |
SQLCLASS 0A (Feature Not Supported) | Класс ошибок 0A (Возможность не поддерживается) | |
0A000 | Feature Not Supported | Возможность (конструкция) не поддерживается |
SQLCLASS 0B (Invalid Transaction Initiation) | Класс ошибок 0B (неверная инициализация транзакции) | |
0B000 | Invalid transaction initiation | Неверная инициализация транзакции |
SQLCLASS 0L (Invalid Grantor) | Неверный грантодатель | |
0L000 | Invalid grantor | Неверный грантодатель |
SQLCLASS 0P (Invalid Role Specification) | Класс ошибок 0P (неверная спецификация роли) | |
0P000 | Invalid role specification | Неверная спецификация роли |
SQLCLASS 0U (Attempt to Assign to Non-Updatable Column) | Класс ошибок 0U (попытка присвоения не обновляемому столбцу) | |
0U000 | Attempt to assign to non-updatable column | Попытка присвоения не обновляемому столбцу |
SQLCLASS 0V (Attempt to Assign to Ordering Column) | Класс ошибок 0V (попытка присвоения сортируемому столбцу) | |
0V000 | Attempt to assign to Ordering column | Попытка присвоения сортируемому столбцу |
SQLCLASS 20 (Case Not Found For Case Statement) | Класс 20 (не обнаружено вариантов для предложения CASE) | |
20000 | Case not found for case statement | Не обнаружено вариантов для предложения CASE |
SQLCLASS 21 (Cardinality Violation) | Класс 21 (Нарушения определения) | |
21000 | Cardinality violation | Нарушение определения |
21S01 | Insert value list does not match column list | Список вставляемых значений не соответствует списку столбцов |
21S02 | Degree of derived table does not match column list | Состояние производной таблицы не соответствует списку столбцов |
SQLCLASS 22 (Data Exception) | Класс ошибок 22 (исключения, вызванные данными) | |
22000 | Data exception | Исключения данных |
22001 | String data, right truncation | Строковые данные, усечены справа |
22002 | Null value, no indicator parameter | Значение NULL, параметр не обозначен |
22003 | Numeric value out of range | Числовое значение вышло за предел допустимого |
22004 | Null value not allowed | Значение NULL не допустимо |
22005 | Error in assignment | Ошибка присваивания |
22006 | Null value in field reference | Значение NULL в поле ссылки |
22007 | Invalid datetime format | Неверный формат даты/времени |
22008 | Datetime field overflow | Переполнение в поле даты/времени |
22009 | Invalid time zone displacement value | Неверная временная зона, неверное значение |
2200A | Null value in reference target | Значение NULL в целевой ссылке |
2200B | Escape character conflict | Конфликт символа управления |
2200C | Invalid use of escape character | Неверное использование управляющего символа |
2200D | Invalid escape octet | Неверный октет для управляющего символа |
2200E | Null value in array target | Значение NULL в массиве назначения |
2200F | Zero-length character string | Нулевая длина строки символов |
2200G | Most specific type mismatch | Наиболее определенное несоответствие типов |
22010 | Invalid indicator parameter value | Неверный индикатор значения параметра |
22011 | Substring error | Ошибка подстроки |
22012 | Division by zero | Деление на ноль |
22014 | Invalid update value | Неверное значение в операции update |
22015 | Interval field overflow | Переполнение интервала в поле |
22018 | Invalid character value for cast | Неверный символ для преобразования типов |
22019 | Invalid escape character | Неверный символ управления |
2201B | Invalid regular expression | Неверное регулярное выражение |
2201C | Null row not permitted in table | Запись содержащая NULL не допустима для таблицы |
22020 | Invalid limit value | Неверное значение лимита |
22021 | Character not in repertoire | Символ вне диапазона |
22022 | Indicator overflow | Переполнение индикатора |
22023 | Invalid parameter value | Неверное значение параметра |
22024 | Character string not properly terminated | Символьная строка имеет некорректный замыкающий символ |
22025 | Invalid escape sequence | Неверная управляющая последовательность |
22026 | String data, length mismatch | Строковые данные, длина неверная |
22027 | Trim error | Ошибка операции TRIM |
22028 | Row already exists | Строка уже существует |
2202D | Null instance used in mutator function | NULL экземпляр используется для мутирующей функции |
2202E | Array element error | Ошибка элемента массива |
2202F | Array data, right truncation | Данные массива, обрезание справа |
SQLCLASS 23 (Integrity Constraint Violation) | Класс ошибок 23 (Нарушение ограничения целостности) | |
23000 | Integrity constraint violation | Нарушение ограничения целостности |
SQLCLASS 24 (Invalid Cursor State) | Класс ошибок 24 (неверное состояние курсора) | |
24000 | Invalid cursor state | Неверное состояние курсора |
24504 | The cursor identified in the UPDATE, DELETE, SET, or GET statement is not positioned on a row | Курсор определенный для UPDATE, DELETE, SET или GET операции не позиционирован по строке |
SQLCLASS 25 (Invalid Transaction State) | Класс ошибок 25 (неверное состояние транзакции) | |
25000 | Invalid transaction state | Неверное состояние транзакции |
25S01 | Transaction state | Неверное состояние транзакции |
25S02 | Transaction is still active | Транзакция до сих пор активная |
25S03 | Transaction is rolled back | Транзакция откачена |
SQLCLASS 26 (Invalid SQL Statement Name) | Класс ошибок 26 (неверное имя SQL предложения) | |
26000 | Invalid SQL statement name | Неверное имя SQL предложения |
SQLCLASS 27 (Triggered Data Change Violation) | Класс ошибок 27 (ошибки изменения данных триггером) | |
27000 | Triggered data change violation | Ошибки изменения данных триггером |
SQLCLASS 28 (Invalid Authorization Specification) | Класс ошибок 28 (неверная спецификация авторизации) | |
28000 | Invalid authorization specification | Неверная спецификация авторизации |
SQLCLASS 2B (Dependent Privilege Descriptors Still Exist) | Класс ошибок 2B (зависимые описания привилегий еще существуют) | |
2B000 | Dependent privilege descriptors still exist | Зависимые описания привилегий еще существуют |
SQLCLASS 2C (Invalid Character Set Name) | Класс ошибок 2С (неверное имя набора символов) | |
2C000 | Invalid character set name | Неверное имя набора символов |
SQLCLASS 2D (Invalid Transaction Termination) | Класс ошибок 2D (неверное завершение транзакции) | |
2D000 | Invalid transaction termination | Неверное завершение транзакции |
SQLCLASS 2E (Invalid Connection Name) | Класс ошибок 2E (неверное имя соединения) | |
2E000 | Invalid connection name | Неверное имя соединения |
SQLCLASS 2F (SQL Routine Exception) | Класс ошибок 2F (процедурные исключения SQL) | |
2F000 | SQL routine exception | Процедурное исключение SQL |
2F002 | Modifying SQL-data not permitted | На модификацию SQL данных нет доступа |
2F003 | Prohibited SQL-statement attempted | Встретилось запрещенное SQL предложение |
2F004 | Reading SQL-data not permitted | Нет доступа на чтение SQL данных |
2F005 | Function executed no return statement | Исполняемая функция не имеет возвращаемого выражения |
SQLCLASS 33 (Invalid SQL Descriptor Name) | Класс ошибок 33 (неверное имя SQL описания) | |
33000 | Invalid SQL descriptor name | Неверное имя SQL описания |
SQLCLASS 34 (Invalid Cursor Name) | Класс ошибок 34 (неверное имя курсора) | |
34000 | Invalid cursor name | Неверное имя курсора |
SQLCLASS 35 (Invalid Condition Number) | Класс ошибок 35 (неверный номер условия) | |
35000 | Invalid condition number | Неверный номер условия |
SQLCLASS 36 (Cursor Sensitivity Exception) | Класс ошибок 36 (ошибка восприятия курсора) | |
36001 | Request rejected | Запрос отвергнут |
36002 | Request failed | Запрос ошибочный |
SQLCLASS 37 (Invalid Identifier) | Класс ошибок 37 (неверный идентификатор) | |
37000 | Invalid identifier | Неверный идентификатор |
37001 | Identifier too long | Идентификатор слишком длинный |
SQLCLASS 38 (External Routine Exception) | Класс ошибок 38 (ошибки внешних процедур) | |
38000 | External routine exception | Ошибка внешней процедуры |
SQLCLASS 39 (External Routine Invocation Exception) | Класс ошибок 39 (ошибка вызова внешней процедуры) | |
39000 | External routine invocation exception | Ошибка вызова внешней процедуры |
SQLCLASS 3B (Invalid Save Point) | Класс ошибок 3B (неверная точка сохранения) | |
3B000 | Invalid save point | Неверная точка сохранения |
SQLCLASS 3C (Ambiguous Cursor Name) | Класс ошибок 3C (имя курсора неоднозначное) | |
3C000 | Ambiguous cursor name | Имя курсора неоднозначное |
SQLCLASS 3D (Invalid Catalog Name) | Класс ошибок 3D (неверное имя каталога) | |
3D000 | Invalid catalog name | Неверное имя каталога |
3D001 | Catalog name not found | Каталог с таким именем не обнаружен |
SQLCLASS 3F (Invalid Schema Name) | Класс ошибок 3F (неверное имя схемы) | |
3F000 | Invalid schema name | Неверное имя схемы |
SQLCLASS 40 (Transaction Rollback) | Класс ошибок 40 (откат транзакции) | |
40000 | Ongoing transaction has been rolled back | Текущая транзакция была откачена |
40001 | Serialization failure | Отказ сериализации |
40002 | Transaction integrity constraint violation | Нарушение условия целостности транзакции |
40003 | Statement completion unknown | Неизвестно состояние завершения транзакции |
SQLCLASS 42 (Syntax Error or Access Violation) | Класс ошибок 42 (синтаксическая ошибка или ошибка доступа) | |
42000 | Syntax error or access violation | Синтаксическая ошибка или ошибка доступа |
42702 | Ambiguous column reference | Неоднозначная ссылка на столбец |
42725 | Ambiguous function reference | Неоднозначная ссылка на функцию |
42818 | The operands of an operator or function are not compatible | Операнды оператора или функции являются не совместимыми |
42S01 | Base table or view already exists | Таблица в базе или view уже существует |
42S02 | Base table or view not found | Таблица в базе или view не найдена |
42S11 | Index already exists | Индекс уже существует |
42S12 | Index not found | Индекс не найден |
42S21 | Column already exists | Столбец уже существует |
42S22 | Column not found | Столбец не найден |
SQLCLASS 44 (With Check Option Violation) | Класс ошибок 44 (нарушение опции WITH CHECK) | |
44000 | WITH CHECK OPTION Violation | Нарушение опции WITH CHECK |
SQLCLASS 45 (Unhandled User-defined Exception) | Класс ошибок 45 (необработанное исключение определенное пользователем) | |
45000 | Unhandled user-defined exception | Необработанное исключение, определенное пользователем |
SQLCLASS 54 (Program Limit Exceeded) | Класс ошибок 54 (превышены ограничения программы) | |
54000 | Program limit exceeded | Превышены ограничения программы |
54001 | Statement too complex | Выражение слишком сложное |
54011 | Too many columns | Слишком много столбцов |
54023 | Too many arguments | Слишком много аргументов |
SQLCLASS HY (CLI-specific Condition) | Класс ошибок HY (условия CLI-specific) | |
HY000 | CLI-specific condition | Условия CLI-specific |
HY001 | Memory allocation error | Ошибка выделения памяти |
HY003 | Invalid data type in application descriptor | Неверный тип данных в дескрипторе приложения |
HY004 | Invalid data type | Неверный тип данных |
HY007 | Associated statement is not prepared | Связанный оператор не подготовлен |
HY008 | Operation canceled | Операция отменена |
HY009 | Invalid use of null pointer | Неправильное использование нулевого указателя |
HY010 | Function sequence error | Ошибка последовательности функций |
HY011 | Attribute cannot be set now | Атрибут не может быть установлен сейчас |
HY012 | Invalid transaction operation code | Неверный код транзакции операции |
HY013 | Memory management error | Ошибка управления памятью |
HY014 | Limit on the number of handles exceeded | Достигнут лимит числа указателей |
HY015 | No cursor name available | Недоступен курсор без имени |
HY016 | Cannot modify an implementation row descriptor | Невозможно изменить реализацию дескриптора строки |
HY017 | Invalid use of an automatically allocated descriptor handle | Неверное использование автоматически выделяемого дескриптора указателей |
HY018 | Server declined the cancellation request | Сервер отклонил запрос на отмену |
HY019 | Non-string data cannot be sent in pieces | Не строковые данные не могут быть отправлены по кускам |
HY020 | Attempt to concatenate a null value | Попытка конкатенации значения NULL |
HY021 | Inconsistent descriptor information | Противоречивая информация о дескрипторе |
HY024 | Invalid attribute value | Неверное значение атрибута |
HY055 | Non-string data cannot be used with string routine | Не строковые данные не могут быть использованы со строковой процедурой |
HY090 | Invalid string length or buffer length | Неверная длина строки или длина буфера |
HY091 | Invalid descriptor field identifier | Неверный дескриптор идентификатора поля |
HY092 | Invalid attribute identifier | Неверный идентификатор атрибута |
HY095 | Invalid FunctionId specified | Неверное указание ID функции |
HY096 | Invalid information type | Неверный тип информации |
HY097 | Column type out of range | Тип столбца вне диапазона |
HY098 | Scope out of range | Определение вне диапазона |
HY099 | Nullable type out of range | Типы с допустимыми NULL вне диапазона |
HY100 | Uniqueness option type out of range | Тип опции "уникальность" вне диапазона |
HY101 | Accuracy option type out of range | Тип опции "точность" вне диапазона |
HY103 | Invalid retrieval code | Неверный код поиска |
HY104 | Invalid LengthPrecision value | Неверное значение длина/точность |
HY105 | Invalid parameter type | Неверный тип параметра |
HY106 | Invalid fetch orientation | Неверное направление для fetch |
HY107 | Row value out of range | Значение строки вне диапазона |
HY109 | Invalid cursor position | Неверная позиция курсора |
HY110 | Invalid driver completion | Неверный код завершения драйвера |
HY111 | Invalid bookmark value | Неверное значение метки bookmark |
HYC00 | Optional feature not implemented | Опциональная функция не реализована |
HYT00 | Timeout expired | Достигнут тайм-аут |
HYT01 | Connection timeout expired | Достигнут тайм-аут соединения |
SQLCLASS XX (Internal Error) | SQLCLASS XX (внутренние ошибки) | |
XX000 | Internal error | Внутренняя ошибка |
XX001 | Data corrupted | Данные разрушены |
XX002 | Index corrupted | Индекс разрушен |
Таблица ошибок содержит числовое и символьное значения GDSCODE, текст сообщения об ошибке и описание ошибки. Также приводится SQLCODE ошибки.
В настоящее время SQLCODE считаются устаревшим. В следующих версиях поддержка SQLCODE может полностью прекратиться.
Таблица B.2. Коды ошибок GDSCODE, SQLCODE и их описание
SQLCODE | GDSCODE | SYMBOL |
TEXT Описание и перевод сообщения. |
---|---|---|---|
101 | 335544366 | Segment |
Segment buffer length shorter than expected. Длина буфера сегмента меньше, чем ожидается. |
100 | 335544338 | from_no_match |
No match for first value expression. Нет соответствия для первого значения выражения. |
100 | 335544354 | no_record |
Invalid database key. Неверный ключ базы данных. |
100 | 335544367 | segstr_eof |
Attempted retrieval of more segments than exist. Попытка обращения к сегменту большему чем их существует. |
100 | 335544374 | stream_eof |
Attempt to fetch past the last record in a record stream. Попытка получения в потоке записей записи, следующей за последней. |
0 | 335741039 | gfix_opt_SQL_dialect |
-sql_dialect set database dialect n. |
0 | 335544875 | bad_debug_format |
Bad debug info format. Неверный формат отладочной информации. |
-84 | 335544554 | nonsql_security_rel |
Table/procedure has non-SQL security class defined. Для таблицы/процедуры определен НЕ-SQL класс безопасности. |
-84 | 335544555 | nonsql_security_fld |
Column has non-SQL security class defined. Для столбца определен НЕ-SQL класс безопасности. |
-84 | 335544668 | dsql_procedure_use_err |
Procedure @1 does not return any values. Процедура @1 не возвращает никакого значения. |
-85 | 335544747 | usrname_too_long |
The username entered is too long. Maximum length is 31 bytes. Введенноей имя пользователя очень длинное. Максимальная длина 31 байт. |
-85 | 335544748 | password_too_long |
The password specified is too long. Maximum length is @1 bytes. Введенный пароль очень длинный. Максимальная длина 8 байт. |
-85 | 335544749 | usrname_required |
A username is required for this operation. Для этой операции требуется имя пользователя. |
-85 | 335544750 | password_required |
A password is required for this operation. Для этой операции требуется пароль. |
-85 | 335544751 | bad_protocol |
The network protocol specified is invalid. Указан неверный сетевой протокол. |
-85 | 335544752 | dup_usrname_found |
A duplicate user name was found in the security database. В базе данных безопасности обнаружено дублирование имен пользователей. |
-85 | 335544753 | usrname_not_found |
The user name specified was not found in the security database. Указанное имя пользователя не найдено в базе данных безопасности. |
-85 | 335544754 | error_adding_sec_record |
An error occurred while attempting to add the user. Ошибка произошла при попытке добавления пользователя. |
-85 | 335544755 | error_modifying_sec_record |
An error occurred while attempting to modify the user record. Ошибка произошла при попытке редактирования записи о пользователе. |
-85 | 335544756 | error_deleting_sec_record |
An error occurred while attempting to delete the user record. Ошибка произошла при попытке удаления записи о пользователе. |
-85 | 335544757 | error_updating_sec_db |
An error occurred while updating the security database. Ошибка произошла при изменении базы данных безопасности. |
-103 | 335544571 | dsql_constant_err |
Data type for constant unknown. Неизвестный тип данных для константы. |
-104 | 336003075 | dsql_transitional_numeric |
Precision 10 to 18 changed from DOUBLE PRECISION in SQL dialect 1 to 64-bit scaled integer in SQL dialect 3. Точность от 10 до 18 в SQL диалекте 1 изменена для DOUBLE PRECISION до 64 битного масштабируемого целого в диалекте 3. |
-104 | 336003077 | sql_db_dialect_dtype_unsupport |
Database SQL dialect @1 does not support reference to @2 datatype. База данных SQL с диалектом @1 не поддерживает ссылку на @2 тип данных. |
-104 | 336003087 | dsql_invalid_label |
Label @1 @2 in the current scope. Метка @1 @2 находится в текущей зоне видимости. |
-104 | 336003088 | dsql_datatypes_not_comparable |
Datatypes @1are not comparable in expression @2. Тип данных @1 не сравним в выражении @2. |
-104 | 335544343 | invalid_blr |
Invalid request BLR at offset @1. Неверный запрос BLR со смещением @1. |
-104 | 335544390 | syntaxerr |
BLR syntax error: expected @1 at offset @2, encountered @3. Ошибка синтаксиса BLR: ожидается @1 по смещению @2, встречено @3. |
-104 | 335544425 | ctxinuse |
Context already in use (BLR error). Контекст находится в использовании (ошибка BLR ). |
-104 | 335544426 | ctxnotdef |
Context not defined (BLR error). Контекст не определен (ошибка BLR). |
-104 | 335544429 | badparnum |
Bad parameter number. Неверный номер параметра. |
-104 | 335544440 | bad_msg_vec |
- |
-104 | 335544456 | invalid_sdl |
Invalid slice description language at offset @1. Неверный фрагмент языка описания по смещению @1. |
-104 | 335544570 | dsql_command_err |
Invalid command. Неверная команда. |
-104 | 335544579 | dsql_internal_err |
Internal error. Внутренняя ошибка. |
-104 | 335544590 | dsql_dup_option |
Option specified more than once. Режим указан более одного раза. |
-104 | 335544591 | dsql_tran_err |
Unknown transaction option. Неизвестный режим транзакции. |
-104 | 335544592 | dsql_invalid_array |
Invalid array reference. Неверная ссылка на массив. |
-104 | 335544608 | command_end_err |
Unexpected end of command. Неожиданное завершение команды. |
-104 | 335544612 | token_err |
Token unknown. Неизвестный синтаксический элемент. |
-104 | 335544634 | dsql_token_unk_err |
Token unknown - line @1, column @2. Неизвестный синтаксический элемент – строка @1, символ @2. |
-104 | 335544709 | dsql_agg_ref_err |
Invalid aggregate reference. Неверная ссылка на агрегат. |
-104 | 335544714 | invalid_array_id |
Invalid blob id. Неверный идентификатор BLOB. |
-104 | 335544730 | cse_not_supported |
Client/Server Express not supported in this release. Client/Server Express не поддерживается в этом релизе. |
-104 | 335544743 | token_too_long |
Token size exceeds limit. Размер синтаксического элемента превышает предел. |
-104 | 335544763 | invalid_string_constant |
A string constant is delimited by double quotes. Строковая константа определена в кавычках. |
-104 | 335544764 | transitional_date |
DATE must be changed to TIMESTAMP. DATE должно измениться TIMESTAMP. |
-104 | 335544796 | sql_dialect_datatype_unsupport |
Client SQL dialect @1 does not support reference to @2 datatype. SQL диалект @1 клиента не поддерживает ссылку на тип данных @2. |
-104 | 335544798 | depend_on_uncommitted_rel |
You created an indirect dependency on uncommitted metadata. You must roll back the current transaction. Вы создали непрямую зависимость на неподтвержденные метаданные. Вы должны отменить текущую транзакцию. |
-104 | 335544821 | dsql_column_pos_err |
Invalid column position used in the @1 clause. В предложении @1 используется неверная позиция столбца. |
-104 | 335544822 | dsql_agg_where_err |
Cannot use an aggregate function in a WHERE clause, use HAVING instead. Невозможно использовать агрегатную функцию в предложении WHERE, заместо этого используйте HAVING. |
-104 | 335544823 | dsql_agg_group_err |
Cannot use an aggregate function in a GROUP BY clause. Невозможно использовать агрегатную функцию в кляузе GROUP BY. |
-104 | 335544824 | dsql_agg_column_err |
Invalid expression in the @1 (not contained in either an aggregate function or the GROUP BY clause). Неверное выражение в @1 ( ни содержится ни в агрегатной функции ни в кляузе GROUP BY). |
-104 | 335544825 | dsql_agg_having_err |
Invalid expression in the @1 (neither an aggregate function nor a part of the GROUP BY clause). Неверное выражение в @2 ( не агрегатная функция, ни часть кляузы GROUP BY). |
-104 | 335544826 | dsql_agg_nested_err |
Nested aggregate functions are not allowed. Вложенные агрегатные функции не допустимы. |
-104 | 335544849 | malformed_string |
Malformed string. Искаженная (некорректная) строка. |
-104 | 335544851 | command_end_err2 |
Unexpected end of command- line @1, column @2. Неожиданный конец команд – линия @1, колонка @2. |
-104 | 336397215 | dsql_max_sort_items |
Cannot sort on more than 255 items. Не могу сортировать условие более чем из 255 элементов. |
-104 | 336397216 | dsql_max_group_items |
Cannot group on more than 255 items. Не могу группировать более чем 255 элементов. |
-104 | 336397217 | dsql_conflicting_sort_field |
Cannot include the same field (@1.@2) twice in the ORDER BY clause with conflicting sorting options. Не могу включить такое же поле (@1.@2) дважды в кляузу ORDER BY с противоречивыми параметрами сортировки. |
-104 | 336397218 | dsql_derived_table_more_columns |
Column list from derived table @1 has more columns than the number of items in its SELECT statement. Список столбцов в производной таблице @1 содержит больше столбцов, чем количество элементов в SELECT. |
-104 | 336397219 | dsql_derived_table_less_columns |
Column list from derived table @1 has less columns than the number of items in its SELECT statement. Список столбцов из производной таблицы @1 имеет меньше столбцов, чем количество элементов в SELECT. |
-104 | 336397220 | dsql_derived_field_unnamed |
No column name specified for column number @1 in derived table @2. Нет имени столбца указанного для столбца под номером @1 в производной таблице @2. |
-104 | 336397221 | dsql_derived_field_dup_name |
Column @1 was specified multiple times for derived table @2. Столбец @1 был указан несколько раз для производной таблицы @2. |
-104 | 336397222 | dsql_derived_alias_select |
Internal dsql error: alias type expected by pass1_expand_select_node. Внутренняя ошибка DSQL: тип псевдоним ожидался pass1_expand_select_node. |
-104 | 336397223 | dsql_derived_alias_field |
Internal dsql error: alias type expected by pass1_field. Внутренняя ошибка DSQL: тип псевдоним ожидался pass1_field. |
-104 | 336397224 | dsql_auto_field_bad_pos |
Internal dsql error: column position out of range in pass1_union_auto_cast. Внутренняя ошибка DSQL: позиция столбца вышла из диапазона в pass1_union_auto_cast. |
-104 | 336397225 | dsql_cte_wrong_reference |
Recursive CTE member (@1) can refer itself only in FROM clause. Рекурсивная часть CTE (@1) может ссылаться сама на себя только в предложении FROM. |
-104 | 336397226 | dsql_cte_cycle |
CTE '@1' has cyclic dependencies. CTE '@1' имеет циклические зависимости. |
-104 | 336397227 | dsql_cte_outer_join |
Recursive member of CTE can't be member of an outer join. Рекурсивная часть CTE не может являться членом outer join. |
-104 | 336397228 | dsql_cte_mult_references |
Recursive member of CTE can't reference itself more than once. Рекурсивный член CTE не может ссылаться на себя более одного раза. |
-104 | 336397229 | dsql_cte_not_a_union |
Recursive CTE (@1) must be an UNION. Рекурсивный CTE (@1) должен содержать UNION. |
-104 | 336397230 | dsql_cte_nonrecurs_after_recurs |
CTE '@1' defined non-recursive member after recursive. В CTE '@1' определена не рекурсивная часть после рекурсии. |
-104 | 336397231 | dsql_cte_wrong_clause |
Recursive member of CTE '@1' has @2 clause. Рекурсивная часть CTE '@1' содержит предложение @2. |
-104 | 336397232 | dsql_cte_union_all |
Recursive members of CTE (@1) must be linked with another members via UNION ALL. Рекурсивная часть CTE (@1) должна быть связана с остальными частями через UNION ALL. |
-104 | 336397233 | dsql_cte_miss_nonrecursive |
Non-recursive member is missing in CTE '@1'. Не рекурсивная часть отсутствует в CTE '@1'. |
-104 | 336397234 | dsql_cte_nested_with |
WITH clause can't be nested. Предложение WITH не может быть вложенным. |
-104 | 336397235 | dsql_col_more_than_once_using |
Column @1 appears more than once in USING clause. Столбец @1 используется более одного раза в предложении USING. |
-104 | 336397237 | dsql_cte_not_used |
CTE "@1" is not used in query. CTE "@1" не используется в запросе. |
-105 | 335544702 | like_escape_invalid |
Invalid ESCAPE sequence. Неверная ESCAPE последовательность. |
-105 | 335544789 | extract_input_mismatch |
Specified EXTRACT part does not exist in input datatype. Указанная часть-параметр для EXTRACT не существует для входного типа данных. |
-150 | 335544360 | read_only_rel |
Attempted update of read-only table. Попытка обновления таблицы только для чтения. |
-150 | 335544362 | read_only_view |
Cannot update read-only view @1. Не могу обновить представление @1 только для чтения. |
-150 | 335544446 | non_updatable |
Not updatable. Не обновляемое. |
-150 | 335544546 | constaint_on_view |
Cannot define constraints on views. Не могу определять констрейны на view. |
-151 | 335544359 | read_only_field |
Attempted update of read - only column. Попытка обновить доступный только для чтения столбец. |
-155 | 335544658 | dsql_base_table |
@1 is not a valid base table of the specified view. @1 не является верной базовой таблицей для указанного view. |
-157 | 335544598 | specify_field_err |
Must specify column name for view select expression. Вы обязаны указать имя столбца для выражения выборки view. |
-158 | 335544599 | num_field_err |
Number of columns does not match select list. Число столбцов не соответствует списку выборки. |
-162 | 335544685 | no_dbkey |
Dbkey not available for multi - table views. Значение Dbkey не доступно для мультитабличных view. |
-170 | 335544512 | prcmismat |
Input parameter mismatch for procedure @1. Входные параметры не соответствуют для процедуры @1. |
-170 | 335544619 | extern_func_err |
External functions cannot have morethan 10 parametrs. UDF не может иметь более чем 10 параметров. |
-170 | 335544850 | prc_out_param_mismatch |
Output parameter mismatch for procedure @1. Несоответствующие входные параметры для процедуры @1. |
-171 | 335544439 | funmismat |
Function @1 could not be matched. Функция @1 не может быть согласована. |
-171 | 335544458 | invalid_dimension |
Column not array or invalid dimensions (expected @1, encountered @2). Столбец не является массивом или неверная размерность (ожидается @1, встретилась @2). |
-171 | 335544618 | return_mode_err |
Return mode by value not allowed for this data type. Режим возврата по значению для допускается для этого типа данных. |
-171 | 335544873 | array_max_dimensions |
Array data type can use up to @1 dimensions. Тип данных массив не может использовать свыше @1 размерностей. |
-172 | 335544438 | funnotdef |
Function @1 is not defined. Функция @1 не определена. |
-203 | 335544708 | dyn_fld_ambiguous |
Ambiguous column reference. Неоднозначная ссылка на столбец. |
-204 | 336003085 | dsql_ambiguous_field_name |
Ambiguous field name between @1 and @2. Неоднозначное имя поля между @1 и @2. |
-204 | 335544463 | gennotdef |
Generator @1 is not defined. Генератор @1 не определен. |
-204 | 335544502 | stream_not_defined |
Reference to invalid stream number. Ссылка на неверный номер потока. |
-204 | 335544509 | charset_not_found |
CHARACTER SET @1 is not defined. Набор символов @1 не определен. |
-204 | 335544511 | prcnotdef |
Procedure @1 is not defined. Процедура @1 не определена. |
-204 | 335544515 | codnotdef |
Status code @1 unknown. Код статуса @1 неизвестен. |
-204 | 335544516 | xcpnotdef |
Exception @1 not defined. Пользовательское исключение @1 не определено. |
-204 | 335544532 | ref_cnstrnt_notfound |
Name of Referential Constraint not defined in constraints table. Имя ссылочного ограничения не определено в таблице ограничений. |
-204 | 335544551 | grant_obj_notfound |
Could not find table/procedure for GRANT. Для операции GRANT не могу найти таблицу / процедуру. |
-204 | 335544568 | text_subtype |
Implementation of text subtype @1 not located. Реализация текстового подтипа @1 не обнаружена. |
-204 | 335544573 | dsql_datatype_err |
Data type unknown. Неизвестный тип данных. |
-204 | 335544580 | dsql_relation_err |
Table unknown. Неизвестная таблица. |
-204 | 335544581 | dsql_procedure_err |
Procedure unknown. Неизвестная процедура. |
-204 | 335544588 | collation_not_found |
COLLATION @1 for CHARACTER SET @2 is not defined. Тип сортировки @1 для набора символов @2 не определен. |
-204 | 335544589 | collation_not_for_charset |
COLLATION @1 is not valid for specified CHARACTER SET. Тип сортировки @1 не верная для указанного набора символов. |
-204 | 335544595 | dsql_trigger_err |
Trigger unknown. Триггер неизвестен. |
-204 | 335544620 | alias_conflict_err |
Alias @1 conflicts with an alias in the same statement. Алиас @1 конфликтует с алиасом в том же выражении. |
-204 | 335544621 | procedure_conflict_error |
Alias @1 conflicts with a procedure in the same statement. Алиас @1 конфликтует в процедурой в том же выражении. |
-204 | 335544622 | relation_conflict_err |
Alias @1 conflicts with a table in the same statement. Алиас @2 конфликтует с таблицей в том же выражении. |
-204 | 335544635 | dsql_no_relation_alias |
There is no alias or table named @1 at this scope level. Там нет алиаса или так именуется таблица на этом уровне области. |
-204 | 335544636 | indexname |
There is no index @1 for table @2. Там нет индекса @1 для таблицы @2. |
-204 | 335544640 | collation_requires_text |
Invalid use of CHARACTER SET or COLLATE. Неверное использование набора символов или типа сортировки. |
-204 | 335544662 | dsql_blob_type_unknown |
BLOB SUB_TYPE @1 is not defined. Подтип BLOB @1 не определен. |
-204 | 335544759 | bad_default_value |
Can not define a not null column with NULL as default value. Не могу описать not null столбец при значении по умолчанию NULL. |
-204 | 335544760 | invalid_clause |
Invalid clause - '@1'. Неверная кляуза - '@1'. |
-204 | 335544800 | too_many_contexts |
Too many Contexts of Relation/Procedure/Views. Maximum allowed is 255. В контексте слишком большое количество таблиц/процедур/ view. Максимально допустимое количество 255. |
-204 | 335544817 | bad_limit_param |
Invalid parameter to FIRST.Only integers >= 0 are allowed. Неверный параметр для FIRST. Возможны только целые числа >=0. |
-204 | 335544818 | bad_skip_param |
Invalid parameter to SKIP. Only integers >= 0 are allowed. Неверный параметр для SKIP. Возможны только целые числа >=0. |
-204 | 335544837 | bad_substring_offset |
Invalid offset parameter @1 to SUBSTRING. Only positive integers are allowed. Неверный параметр смещения @1 для SUBSTRING. Возможны только положительные целые числа. |
-204 | 335544853 | bad_substring_length |
Invalid length parameter @1 to SUBSTRING. Negative integers are not allowed. Неверный параметр длины @1 для SUBSTRING. Отрицательные целые числа не доступны. |
-204 | 335544854 | charset_not_installed |
CHARACTER SET @1 is not installed. Набор символов @1 не установлен. |
-204 | 335544855 | collation_not_installed |
COLLATION @1 for CHARACTER SET @2 is not installed. Сортировка @1 для набора символов @2 не установлена. |
-204 | 335544867 | subtype_for_internal_use |
Blob sub _ types bigger than 1 (text) are for internal use only. Подтип BLOB со значением более чем 1 (TEXT) предназначены только для внутреннего использования. |
-205 | 335544396 | fldnotdef |
Column @1 is not defined in table @2. Столбец @1 не определен в таблице @2. |
-205 | 335544552 | grant_fld_notfound |
Could not find column for GRANT. Не могу найти строку для операции GRANT. |
-205 | 335544883 | fldnotdef2 |
Column @1 is not defined in procedure @2. Столбец @1 не определен в процедуре @2. |
-206 | 335544578 | dsql_field_err |
Column unknown. Столбец неизвестен. |
-206 | 335544587 | dsql_blob_err |
Column is not a BLOB. Столбец не является BLOB. |
-206 | 335544596 | dsql_subselect_err |
Subselect illegal in this context. В данном контексте подзапрос запрещен. |
-206 | 336397208 | dsql_line_col_error |
At line @1, column @2. В строке @1, колонка @2. |
-206 | 336397209 | dsql_unknown_pos |
At unknown line and column. В неизвестных строке и столбце. |
-206 | 336397210 | dsql_no_dup_name |
Column @1 cannot be repeated in @2 statement. Столбец @1 не может быть повторен в выражении @2. |
-208 | 335544617 | order_by_err |
Invalid ORDER BY clause. Неверное предложение ORDER BY. |
-219 | 335544395 | relnotdef |
Table @1 is not defined. Таблица @1 не определена. |
-219 | 335544872 | domnotdef |
Domain @1 is not defined. Домен @1 не определен. |
-230 | 335544487 | walw_err |
WAL Writer error. Ошибка записи WAL. |
-231 | 335544488 | logh_small |
Log file header of @1 too small. Заголовок файла лога @1 слишком мал. |
-232 | 335544489 | logh_inv_version |
Invalid version of log file @1. Неверная версия файла лога @1. |
-233 | 335544490 | logh_open_flag |
Log file @1 not latest in the chain but open flag still set. Лог файл @1 не последний в цепочке, но флаг «открыт» еще установлен. |
-234 | 335544491 | logh_open_flag2 |
Log file @1 not closed properly; database recovery may be required. Лог файл @1 не верно закрыт; может понадобится операция восстановления базы данных. |
-235 | 335544492 | logh_diff_dbname |
Database name in the log file @1 is different. Имя базы данный в файле лога @1 отличается. |
-236 | 335544493 | logf_unexpected_eof |
Unexpected end of log file @1 at offset @2. Неожиданное окончание фала лога @1 по смещению @2. |
-237 | 335544494 | logr_incomplete |
Incomplete log record at offset @1 in log file @2. Неполная запись лога по смещению @1 в файл лога @2. |
-238 | 335544495 | logr_header_small |
Log record header too small at offset @1 in log file @2. Заголовок записи лога слишком мал по смещению @1 в файле лога @2. |
-239 | 335544496 | logb_small |
Log block too small at offset @1 in log file @2. Блок лога слишком мал по смещению @1 в файле лога @2. |
-239 | 335544691 | cache_too_small |
Insufficient memory to allocate page buffer cache. Недостаточно памяти для размещения страниц буфера кэш. |
-239 | 335544693 | log_too_small |
Log size too small. Размер лога слишком мал. |
-239 | 335544694 | partition_too_small |
Log partition size too small. Размер раздела лога слишком мал. |
-243 | 335544500 | no_wal |
Database does not use Write-ahead Log. База данных не использует запись с упреждением лога. |
-257 | 335544566 | start_cm_for_wal |
WAL defined; Cache Manager must be started first. Обнаружено WAL; Менеджер КЭШа должен стартовать первым. |
-260 | 335544690 | cache_redef |
Cache redefined. Кэш переопределен. |
-260 | 335544692 | log_redef |
Log redefined. Лог переопределен. |
-261 | 335544695 | partition_not_supp |
Partitions not supported in series of log file specification. Разделы не поддерживаются в серии спецификации файла журнала. |
-261 | 335544696 | log_length_spec |
Total length of a partitioned log must be specified. Общая длина раздельного лога должна быть определена. |
-281 | 335544637 | no_stream_plan |
Table @1 is not referenced in plan. Таблица @1 не упоминается в плане. |
-282 | 335544638 | stream_twice |
Table @1 is referenced more than once in plan; use aliases to distinguish. Таблица @1 упомянута более раза в плане; используйте алиасы чтобы различить. |
-282 | 335544643 | dsql_self_join |
The table @1 is referenced twice; use aliases to differentiate. Таблица @1 упомянута дважды; используйте алиасы чтобы различить. |
-282 | 335544659 | duplicate_base_table |
Table @1 is referenced twice in view; use an alias to distinguish. Таблица @1 упомянута дважды во view; используйте алиасы чтобы различить. |
-282 | 335544660 | view_alias |
View @1 has more than one base table; use aliases to distinguish. View @1 использует более одного раза базовую таблицу; используйте алиасы чтобы различить их. |
-282 | 335544710 | complex_view |
Navigational stream @1 references a view with more than one base table. Навигационный поток @1 ссылается на view с более чем одной базовой таблицей. |
-283 | 335544639 | stream_not_found |
Table @1 is referenced in the plan but not the from list. В плане ссылаются на таблицу @1, но она не в списке. |
-284 | 335544642 | index_unused |
Index @1 cannot be used in the specified plan. Индекс @1 не может быть использован в указанном плане. |
-291 | 335544531 | primary_key_notnull |
Column used in a PRIMARY constraint must be NOT NULL. Столбец, использованный в первичном ключе должен быть NOT NULL. |
-292 | 335544534 | ref_cnstrnt_update |
Cannot update constraints (RDB$REF_CONSTRAINTS). Не могу обновить ограничения (RDB$REF_CONSTRAINTS). |
-293 | 335544535 | check_cnstrnt_update |
Cannot update constraints (RDB$CHECK_CONSTRAINTS). Не могу обновить ограничения (RDB$CHECK_CONSTRAINTS). |
-294 | 335544536 | check_cnstrnt_del |
Cannot delete CHECK constraint entry (RDB$CHECK_CONSTRAINTS). Не удается удалить ограничение CHECK (RDB$CHECK_CONSTRAINTS). |
-295 | 335544545 | rel_cnstrnt_update |
Cannot update constraints (RDB$RELATION_CONSTRAINTS). Не могу обновить ограничения (RDB$RELATION_CONSTRAINTS). |
-296 | 335544547 | invld_cnstrnt_type |
Internal gds software consistency check (invalid RDB$CONSTRAINT_TYPE). Внутренняя ошибка программного обеспечения на согласованность (неверная таблица RDB$CONSTRAINT_TYPE). |
-297 | 335544558 | check_constraint |
Operation violates check constraint @1 on view or table @2. Операция нарушает проверочное ограничение @1 на представление или таблицу @2. |
-313 | 336003099 | upd_ins_doesnt_match_pk |
UPDATE OR INSERT field list does not match primary key of table @1. В UPDATE OR INSERT список полей не соответствует первичному ключу таблицы @1. |
-313 | 336003100 | upd_ins_doesnt_ match _matching |
UPDATE OR INSERT field list does not match MATCHING clause. В UPDATE OR INSERT список полей не соответствует кляузе MATCHING. |
-313 | 335544669 | dsql_count_mismatch |
Count of column list and variable list do not match. Количество столбцов и переменных в списке не соответствует. |
-314 | 335544565 | transliteration_failed |
Cannot transliterate character between character sets. Не могу подвергнуть транслитерации символ между наборами символов. |
-315 | 336068815 | dyn_dtype_invalid |
Cannot change datatype for column @1.Changing datatype is not supported for BLOB or ARRAY columns. Не могу изменить тип данных для столбца @1. Изменение типа данных не поддерживается для BLOB полей и полей с массивами. |
-383 | 336068814 | dyn_dependency_exists |
Column @1 from table @2 is referenced in @3. Столбец @1 из таблицы @2 упоминается в @3. |
-401 | 335544647 | invalid_operator |
Invalid comparison operator for find operation. Неверный оператор сравнения для операции поиска. |
-402 | 335544368 | segstr_no_op |
Attempted invalid operation on a BLOB. Попытка неверной операции с BLOB. |
-402 | 335544414 | blobnotsup |
BLOB and array data types are not supported for @1 operation. Типы данных BLOB и массив не поддерживаются для операции @1. |
-402 | 335544427 | datnotsup |
Data operation not supported. Операция данных не поддерживается. |
-406 | 335544457 | out_of_bounds |
Subscript out of bounds. Индекс вне границ. |
-407 | 335544435 | nullsegkey |
Null segment of UNIQUE KEY. Null сегмент для уникального ключа. |
-413 | 335544334 | convert_error |
Conversion error from string "@1". Ошибка конвертации для строки "@1". |
-413 | 335544454 | nofilter |
Filter not found to convert type @1 to type @2. Фильтр не обнаружен для конвертации типа @1 в тип @2. |
-413 | 335544860 | blob_convert_error |
Unsupported conversion to target type BLOB (subtype @1). Не поддерживается преобразование в целевой тип BLOB (подтип @1). |
-413 | 335544861 | array_convert_error |
Unsupported conversion to target type ARRAY. Не поддерживается преобразование в целевой тип массив. |
-501 | 335544577 | dsql_cursor_close_err |
Attempt to reclose a closed cursor. Попытка перезакрыть закрытый курсор. |
-502 | 336003090 | dsql_cursor_redefined |
Statement already has a cursor @1 assigned. Для предложения уже имеется назначенный @1 курсор. |
-502 | 336003091 | dsql_cursor_not_found |
Cursor @1 is not found in the current context. Курсор @1 не обнаружен для текущего контекста. |
-502 | 336003092 | dsql_cursor_exists |
Cursor @1 already exists in the current context. Курсор @1 уже существует для указанного контекста. |
-502 | 336003093 | dsql_cursor_rel_ambiguous |
Relation @1 is ambiguous in cursor @2. Соотношение @1 неоднозначно в курсоре @2. |
-502 | 336003094 | dsql_cursor_rel_not_found |
Relation @1 is not found in cursor @2. Отношение @1 не найдено в курсоре @2. |
-502 | 336003095 | dsql_cursor_not_open |
Cursor is not open. Курсор не открыт. |
-502 | 335544574 | dsql_decl_err |
Invalid cursor declaration. Неверная декларация курсора. |
-502 | 335544576 | dsql_cursor_open_err |
Attempt to reopen an open cursor. Попытка переоткрыть открытый курсор. |
-504 | 336003089 | dsql_cursor_invalid |
Empty cursor name is not allowed. Для курсора не доступно пустое имя. |
-504 | 335544572 | dsql_cursor_err |
Invalid cursor reference. Недопустимая ссылка на курсор. |
-508 | 335544348 | no_cur_rec |
No current record for fetch operation. Нет текущей записи для операции FETCH. |
-510 | 335544575 | dsql_cursor_update_err |
Cursor @1 is not updatable. Курсор @1 является не обновляемым. |
-518 | 335544582 | dsql_request_err |
Request unknown. Запрос неизвестен. |
-519 | 335544688 | dsql_open_cursor_request |
The prepare statement identifies a prepare statement with an open cursor. Подготовка выражения определила подготовку выражения с открытием курсора. |
-530 | 335544466 | foreign_key |
Violation of FOREIGN KEY constraint "@1" on table "@2". Нарушение ограничения внешнего ключа @1 для таблицы @2. |
-530 | 335544838 | foreign_key_target_doesnt_exist |
Foreign key reference target does not exist. Ссылка на целевое значение внешнего ключа не существует. |
-530 | 335544839 | foreign_key_references_present |
Foreign key references are present for the record. Ссылки внешнего ключа присутствуют для записи. |
-531 | 335544597 | dsql_crdb_prepare_err |
Cannot prepare a CREATE DATABASE/SCHEMA statement. Не могу подготовить к выполнению оператор CREATE DATABASE/SCHEMA. |
-532 | 335544469 | trans_invalid |
Transaction marked invalid by I/O error. Транзакция помечена как недействительная из-за ошибки ввода-вывода. |
-551 | 335544352 | no_priv |
No permission for @1 access to @2 @3. Нет разрешения @1 для доступа к @2 @3. |
-551 | 335544790 | insufficient_svc_privileges |
Service @1 requires SYSDBA permissions. Reattach to the Service Manager using the SYSDBA account. Сервис @1 требует привилегии SYSDBA. Переприсоединитесь к менеджеру сервисов используя учетную запись SYSDBA. |
-552 | 335544550 | not_rel_owner |
Only the owner of a table may reassign ownership. Только владелец таблицы может переназначить права владения. |
-552 | 335544553 | grant_nopriv |
User does not have GRANT privileges for operation. Пользователь не имеет привилегий для операции GRANT. |
-552 | 335544707 | grant_nopriv_on_base |
User does not have GRANT privileges on base table/view for operation. Пользователь не имеет GRANT привилегии на таблицу / представление для этой операции. |
-553 | 335544529 | existing_priv_mod |
Cannot modify an existing user privilege. Не могу изменить существующие пользовательские привилегии. |
-595 | 335544645 | stream_crack |
The current position is on a crack. Текущая позиция «в трещине». |
-596 | 335544644 | stream_bof |
Illegal operation when at beginning of stream. Неверная операция при начале потока. |
-597 | 335544632 | dsql_file_length_err |
Preceding file did not specify length, so @1 must include starting page number. Предыдущий файл не указал длины, так что @1 должен включать число стартовых страниц. |
-598 | 335544633 | dsql_shadow_number_err |
Shadow number must be a positive integer. Номер тени должен быть целым положительным числом. |
-599 | 335544607 | node_err |
Gen.c: node not supported. Gen.c: ноды (узлы) не поддерживаются. |
-599 | 335544625 | node_name_err |
A node name is not permitted in a secondary, shadow, cache or log file name. Имя узла не допускается в именах вторичного, теневого, КЭШа или в имени файла лога. |
-600 | 335544680 | crrp_data_err |
Sort error: corruption in data structure. Ошибка сортировки: разрушения в структуре данных. |
-601 | 335544646 | db_or_file_exists |
Database or file exists. База данных или файл не существует. |
-604 | 335544593 | dsql_max_arr_dim_exceeded |
Array declared with too many dimensions. Массив задекларирован со слишком многими размерностями. |
-604 | 335544594 | dsql_arr_range_error |
Illegal array dimension range. Неверный диапазон размерности массива. |
-605 | 335544682 | dsql_field_ref |
Inappropriate self-reference of column. Жалоба на ссылку «сам на себя» столбца. |
-607 | 336003074 | dsql_dbkey_from_non_table |
Cannot SELECT RDB$DB_KEY from a stored procedure. Невозможно выполнить SELECT RDB$DB_KEY из хранимой процедуры. |
-607 | 336003086 | dsql_udf_return_pos_err |
External function should have return position between 1 and @1. Внешняя функция должна иметь позицию возврата между 1 и @1. |
-607 | 336003096 | dsql_type_not_supp_ext_tab |
Data type @1 is not supported for EXTERNAL TABLES. Relation '@2', field '@3'. Тип данных @1 не поддерживается для внешних таблиц. Таблица '@2', поле '@3'. |
-607 | 335544351 | no_meta_update |
Unsuccessful metadata update. Неудачное обновление метаданных. |
-607 | 335544549 | systrig_update |
Cannot modify or erase a system trigger. Не возможно изменить или стереть системный триггер. |
-607 | 335544657 | dsql_no_blob_array |
Array/BLOB/DATE data types not allowed in arithmetic. Типы данных Массив/BLOB/даты не возможны для арифметических операций. |
-607 | 335544746 | reftable_requires_pk |
"REFERENCES table" without "(column)" requires PRIMARY KEY on referenced table. "Таблицы ссылок" без "(столбца)" требуют первичного ключа связанной таблице. |
-607 | 335544815 | generator_name |
GENERATOR @1. |
-607 | 335544816 | udf_name |
UDF @1. |
-607 | 335544858 | must_have_phys_field |
Can't have relation with only computed fields or constraints. Невозможна таблица состоящая только из одних вычисляемых полей или ограничений. |
-607 | 336397206 | dsql_table_not_found |
Table @1 does not exist. Таблица @1 не существует. |
-607 | 336397207 | dsql_view_not_found |
View @1 does not exist. Представление @1 не существует. |
-607 | 336397212 | dsql_no_array_computed |
Array and BLOB data types not allowed in computed field. Типы данных массив и BLOB не подходят для вычисляемых полей. |
-607 | 336397214 | dsql_only_can_subscript_array |
Scalar operator used on field @1 which is not an array. Скалярный оператор используется по полю @1, которое не является массивом. |
-612 | 336068812 | dyn_domain_name_exists |
Cannot rename domain @1 to @2. A domain with that name already exists. Не возможно переименовать домен из @1 в @2. Домен с таким именем уже существует. |
-612 | 336068813 | dyn_field_name_exists |
Cannot rename column @1 to @2.A column with that name already exists in table @3. Не возможно переименовать столбец @1 в @2. Столбец с таким именем уже существует в таблице @3. |
-615 | 335544475 | relation_lock |
Lock on table @1 conflicts with existing lock. Блокировка в таблице @1 конфликтует с существующей блокировкой. |
-615 | 335544476 | record_lock |
Requested record lock conflicts with existing lock. Требуемая блокировка записи конфликтует с существующей блокировкой. |
-615 | 335544507 | range_in_use |
Refresh range number @1 already in use. Обновленный диапазон номеров @1 уже используется. |
-616 | 335544530 | primary_key_ref |
Cannot delete PRIMARY KEY being used in FOREIGN KEY definition. Не могу удалить первичный ключ используемый в определении внешнего ключа. |
-616 | 335544539 | integ_index_del |
Cannot delete index used by an Integrity Constraint. Не возможно удалить индекс используемый в ограничении. |
-616 | 335544540 | integ_index_mod |
Cannot modify index used by an Integrity Constraint. Не могу изменить индекс используемый в ограничении. |
-616 | 335544541 | check_trig_del |
Cannot delete trigger used by a CHECK Constraint. Не могу удалить триггер используемый в ограничении типа CHECK. |
-616 | 335544543 | cnstrnt_fld_del |
Cannot delete column being used in an Integrity Constraint. Не могу удалить столбец используемый в ограничении целостности. |
-616 | 335544630 | dependency |
There are @1 dependencies. Есть @1 зависимостей. |
-616 | 335544674 | del_last_field |
Last column in a table cannot be deleted. Последний столбец таблицы не может быть удален. |
-616 | 335544728 | integ_index_deactivate |
Cannot deactivate index used by an integrity constraint. Не могу деактивировать индекс используемый в ограничении целостности. |
-616 | 335544729 | integ_deactivate_primary |
Cannot deactivate index used by a PRIMARY/UNIQUE constraint. Не могу деактивировать индекс используемый в ограничении первичного ключа/уникальности. |
-617 | 335544542 | check_trig_update |
Cannot update trigger used by a CHECK Constraint. Не могу обновить триггер используемый в ограничении типа CHECK. |
-617 | 335544544 | cnstrnt_fld_rename |
Cannot rename column being used in an Integrity Constraint. Не могу переименовать столбец, используемый в ограничении целостности. |
-618 | 335544537 | integ_index_seg_del |
Cannot delete index segment used by an Integrity Constraint. Не могу удалить сегмент индекса, используемый в ограничении целостности. |
-618 | 335544538 | integ_index_seg_mod |
Cannot update index segment used by an Integrity Constraint. Не могу обновить сегмент индекса, используемый в ограничении целостности. |
-625 | 335544347 | not_valid |
Validation error for column @1, value "@2". Ошибка проверки данных для столбца @1, значение "@2". |
-625 | 335544879 | not_valid_for_var |
Validation error for variable @1, value "@2". Ошибка проверки данных для переменной @1, значение "@2". |
-625 | 335544880 | not_valid_for |
Validation error for @1, value "@2". Ошибка проверки данных для @1, значение "@2". |
-637 | 335544664 | dsql_duplicate_spec |
Duplicate specification of @1- not supported. Дубликат спецификации для @1 - не поддерживается. |
-637 | 336397213 | dsql_implicit_domain_name |
Implicit domain name @1 not allowed in user created domain. Неявное доменное имя @1 не допускается для доменов, создаваемых пользователями. |
-660 | 336003098 | primary_key_required |
Primary key required on table @1. Для таблицы @1 требуется первичный ключ. |
-660 | 335544533 | foreign_key_notfound |
Non-existent PRIMARY or UNIQUE KEY specified for FOREIGN KEY. Не существующий первичный или ключ уникальности указан для внешнего ключа. |
-660 | 335544628 | idx_create_err |
Cannot create index @1. Не могу создать индекс @1. |
-663 | 335544624 | idx_seg_err |
Segment count of 0 defined for index @1. Количество сегментов равное 0 определено для индекса @1. |
-663 | 335544631 | idx_key_err |
Too many keys defined for index @1. Слишком много ключей определено для индекса @1. |
-663 | 335544672 | key_field_err |
Too few key columns found for index @1 (incorrect column name?). Слишком много столбцов ключей обнаружено для индекса @1 (неверные имена столбцов?). |
-664 | 335544434 | keytoobig |
Key size exceeds implementation restriction for index "@1". Размер ключа превысил ограничения реализации для индекса "@1". |
-677 | 335544445 | ext_err |
@1 extension error. @1 ошибка расширения. |
-685 | 335544465 | bad_segstr_type |
Invalid BLOB type for operation. Неверный тип BLOB для операции. |
-685 | 335544670 | blob_idx_err |
Attempt to index BLOB column in index @1. Попытка индексации BLOB столбца в индексе @1. |
-685 | 335544671 | array_idx_err |
Attempt to index array column in index @1. Попытка индексации столбца с типом массив в индексе @1. |
-689 | 335544403 | badpagtyp |
Page @1 is of wrong type (expected @2, found @3). Страница @1 имеет неверный тип (ожидается @2, обнаружена @3). |
-689 | 335544650 | page_type_err |
Wrong page type. Неверный тип страницы. |
-690 | 335544679 | no_segments_err |
Segments not allowed in expression index @1. Сегменты не допускаются в выражении индекса @1. |
-691 | 335544681 | rec_size_err |
New record size of @1 bytes is too big. Новый размер записи в @1 байт является слишком большим. |
-692 | 335544477 | max_idx |
Maximum indexes per table (@1) exceeded. Максимум количества индексов на одну таблицу (@1) превышен. |
-693 | 335544663 | req_max_clones_exceeded |
Too many concurrent executions of the same request. Слишком много конкурентных выполнений одного и того же запроса. |
-694 | 335544684 | no_field_access |
Cannot access column @1 in view @2. Не могу получить доступ к столбцу @1 представления @2. |
-802 | 335544321 | arith_except |
Arithmetic exception, numeric overflow, or string truncation. Арифметическое исключение, числовое переполнение или строковое обрезание. |
-802 | 335544836 | concat_overflow |
Concatenation overflow. Resulting string cannot exceed 32K in length. Переполнение при конкатенации. Результирующая строка не может превышать 32 Кб. |
-803 | 335544349 | no_dup |
Attempt to store duplicate value ( visible to active transactions ) in unique index "@1". Попытка сохранить дубликат значения (видимые при активных транзакциях) в уникальном индексе "@1". |
-803 | 335544665 | unique_key_violation |
Violation of PRIMARY or UNIQUE KEY constraint "@1" on table "@2". Нарушение ограничения первичного или уникального ключа "@1" в таблице "@2". |
-804 | 336003097 | dsql_feature_not_supported_ods |
Feature not supported on ODS version older than @1.@2. Опция не поддерживается в ODS старше чем @1.@2. |
-804 | 335544380 | wronumarg |
Wrong number of arguments on call. Неверное число аргументов в вызове. |
-804 | 335544583 | dsql_sqlda_err |
SQLDA missing or incorrect version, or incorrect number/type of variables. SQLDA отсутствует или неверной версии, либо некорректный номер/тип переменной. |
-804 | 335544584 | dsql_var_count_err |
Count of read - write columns does not equal count of values. Количество столбцов для чтения/записи не равно количеству значений. |
-804 | 335544586 | dsql_function_err |
Function unknown. Функция неизвестна. |
-804 | 335544713 | dsql_sqlda_value_err |
Incorrect values within SQLDA structure. Некорректные значения в SQLDA структуре. |
-804 | 336397205 | dsql_too_old_ods |
ODS versions before ODS@1 are not supported. ODS версии до версии ODS@1 не поддерживаются. |
-806 | 335544600 | col_name_err |
Only simple column names permitted for VIEW WITH CHECK OPTION. Только простые имена столбцов допустимы для опции VIEW WITH CHECK. |
-807 | 335544601 | where_err |
No WHERE clause for VIEW WITH CHECK OPTION. Нет предложения WHERE для опции VIEW WITH CHECK. |
-808 | 335544602 | table_view_err |
Only one table allowed for VIEW WITH CHECK OPTION. Только одна таблица позволена для опции VIEW WITH CHECK. |
-809 | 335544603 | distinct_err |
DISTINCT, GROUP or HAVING not permitted for VIEW WITH CHECK OPTION. Для представления с опцией WITH CHECK OPTION не допустимы DISTINCT, GROUP или HAVING. |
-810 | 335544605 | subquery_err |
No subqueries permitted for VIEW WITH CHECK OPTION. Нет подзапросов разрешенных для for VIEW WITH CHECK OPTION. |
-811 | 335544652 | sing_select_err |
Multiple rows in singleton select. Несколько строк для единичной выпорки. |
-816 | 335544651 | ext_readonly_err |
Cannot insert because the file is readonly or is on a read only medium. Не могу вставить по причине файла только для чтения или среды носителя только для чтения. |
-816 | 335544715 | extfile_uns_op |
Operation not supported for EXTERNAL FILE table @1. Операция не поддерживается для внешней таблицы @1. |
-817 | 336003079 | isc_sql_dialect_conflict_num |
DB dialect @1 and client dialect @2 conflict with respect to numeric precision @3. Диалект БД @1 и диалект клиентской программы @2 конфликтует с соблюдением числовой точности @3. |
-817 | 336003101 | upd_ins_with_complex_view |
UPDATE OR INSERT without MATCHING could not be used with views based on more than one table. UPDATE OR INSERT без MATCHING не могут быть использованы с View базирующимися на более чем одной таблице. |
-817 | 336003102 | dsql_incompatible_trigger_type |
Incompatible trigger type. Несовместимый тип триггера. |
-817 | 336003103 | dsql_db_trigger_type_cant_change |
Database trigger type can't be changed. Триггер типа базы данных не может быть изменен. |
-817 | 335544361 | read_only_trans |
Attempted update during read - only transaction. Попытка выполнить изменения во время выполнения транзакции только для чтения. |
-817 | 335544371 | segstr_no_write |
Attempted write to read-only BLOB. Попытка записи в BLOB только для чтения. |
-817 | 335544444 | read_only |
Operation not supported. Операция не поддерживается. |
-817 | 335544765 | read_only_database |
Attempted update on read - only database. Попытка записи в базу данных находящуюся в режиме только для чтения. |
-817 | 335544766 | must_be_dialect_2_and_up |
SQL dialect @1 is not supported in this database. SQL диалект @1 не поддерживается в этой базе данных. |
-817 | 335544793 | ddl_not_allowed_by_db_sql_dial |
Metadata update statement is not allowed by the current database SQL dialect @1. Обновление метаданных этой строкой не поддерживается из-за текущего диалекта базы данных @1. |
-820 | 335544356 | obsolete_metadata |
Metadata is obsolete. Метаданных являются устаревшими. |
-820 | 335544379 | wrong_ods |
Unsupported on - disk structure for file @1; found @2.@3, support @4.@5. Неподдерживаемая ODS для файла @1, обнаружена @2.@3, поддерживается @4.@5. |
-820 | 335544437 | wrodynver |
Wrong DYN version. Неверная версия DYN. |
-820 | 335544467 | high_minor |
Minor version too high found @1 expected @2. Минорная версия слишком высокая, обнаружена @1, ожидалась @2. |
-820 | 335544881 | need_difference |
Difference file name should be set explicitly for database on raw device. Файл разницы должен быть явно задан для базы данных на «сыром устройстве». |
-823 | 335544473 | invalid_bookmark |
Invalid bookmark handle. Неверный дескриптор закладки. |
-824 | 335544474 | bad_lock_level |
Invalid lock level @1. Неверный уровень блокировки @1. |
-825 | 335544519 | bad_lock_handle |
Invalid lock handle. Неверный дескриптор блокировки. |
-826 | 335544585 | dsql_stmt_handle |
Invalid statement handle. Неверный дескриптор выражения. |
-827 | 335544655 | invalid_direction |
Invalid direction for find operation. Неверное выражение для операции «поиск». |
-827 | 335544718 | invalid_key |
Invalid key for find operation. Неверный ключ для операции поиска. |
-828 | 335544678 | inval_key_posn |
Invalid key position. Неверный положение ключа. |
-829 | 336068816 | dyn_char_fld_too_small |
New size specified for column @1 must be at least @2 characters. Новый размер указанный для столбца @1 должен быть по крайней мере @2 символов. |
-829 | 336068817 | dyn_invalid_dtype_conversion |
Cannot change datatype for @1.Conversion from base type @2 to @3 is not supported. Не могу изменить тип данных для @1. Преобразование из базового типа @2 в @3 не поддерживается. |
-829 | 336068818 | dyn_dtype_conv_invalid |
Cannot change datatype for column @1 from a character type to a non-character type. Не могу помять типа данных для столбца @1 из символьного типа в не символьный. |
-829 | 336068829 | max_coll_per_charset |
Maximum number of collations per character set exceeded. В наборе символов превышено максимальное число наборов сортировок. |
-829 | 336068830 | invalid_coll_attr |
Invalid collation attributes. Неверный атрибуты параметров сортировки. |
-829 | 336068852 | dyn_scale_too_big |
New scale specified for column @1 must be at most @2. Новый масштаб, указанный для столбца @1 должен быть не более @2. |
-829 | 336068853 | dyn_precision_too_small |
New precision specified for column @1 must be at least @2. Новая точность указанная для столбца @1 должна быть по крайней мере @2. |
-829 | 335544616 | field_ref_err |
Invalid column reference. Неверная ссылка столбца. |
-830 | 335544615 | field_aggregate_err |
Column used with aggregate. Столбец используется в агрегатах. |
-831 | 335544548 | primary_key_exists |
Attempt to define a second PRIMARY KEY for the same table. Попытка определить второй первичный ключ для таблицы. |
-832 | 335544604 | key_field_count_err |
FOREIGN KEY column count does not match PRIMARY KEY. Количество столбцов внешнего ключа не совпадает с первичным ключом. |
-833 | 335544606 | expression_eval_err |
Expression evaluation not supported. Вычисляемые выражения не поддерживаются. |
-833 | 335544810 | date_range_exceeded |
Value exceeds the range for valid dates. Значение превышают пределы установленные для действительных дат. |
-834 | 335544508 | range_not_found |
Refresh range number @1 not found. Обновленный диапазон номеров @1 не найден. |
-835 | 335544649 | bad_checksum |
Bad checksum. Неверная контрольная сумма. |
-836 | 335544517 | except |
Exception @1. Исключение @1. |
-836 | 335544848 | except2 |
Exception @1. Исключение @1. |
-837 | 335544518 | cache_restart |
Restart shared cache manager. Рестарт общего менеджера КЭШа. |
-838 | 335544560 | shutwarn |
Database @1 shutdown in @2 seconds. База данных @1 уйдет в состояние шатдаун через @2 секунд. |
-841 | 335544677 | version_err |
Too many versions. Слишком много версий. |
-842 | 335544697 | precision_err |
Precision must be from 1 to 18. Точность должна быть в пределах от 1 до 18. |
-842 | 335544698 | scale_nogt |
Scale must be between zero and precision. Масштаб должен быть между нулем и значением точности. |
-842 | 335544699 | expec_short |
Short integer expected. Ожидается короткое целое. |
-842 | 335544700 | expec_long |
Long integer expected. Ожидается длинное целое. |
-842 | 335544701 | expec_ushort |
Unsigned short integer expected. Ожидается беззнаковое короткое целое. |
-842 | 335544712 | expec_positive |
Positive value expected. Ожидается положительное значение. |
-901 | 335740929 | gfix_db_name |
Database file name (@1) already given. Имя файла базы данных (@1) уже отдано. |
-901 | 336330753 | gbak_unknown_switch |
Found unknown switch. Обнаружена неизвестная опция командной строки. |
-901 | 336920577 | gstat_unknown_switch |
Found unknown switch. Обнаружена неизвестная опция командной строки. |
-901 | 336986113 | fbsvcmgr_bad_am |
Wrong value for access mode. Неверное значение для режима доступа. |
-901 | 335740930 | gfix_invalid_sw |
Invalid switch @1. Неверный параметр командной строки @1. |
-901 | 335544322 | bad_dbkey |
Invalid database key. Неверный ключ базы данных. |
-901 | 336986114 | fbsvcmgr_bad_wm |
Wrong value for write mode. Неверное значение для режима записи. |
-901 | 336330754 | gbak_page_size_missing |
Page size parameter missing. Параметра размера страницы отсутствует. |
-901 | 336920578 | gstat_retry |
Please retry, giving a database name. Пожалуйста повторите, давая имя базы данных. |
-901 | 336986115 | fbsvcmgr_bad_rs |
Wrong value for reserve space. Неверное значение для зарезервированного пространства. |
-901 | 336920579 | gstat_wrong_ods |
Wrong ODS version, expected @1, encountered @2. Неверная версия ODS, ожидается @1, встретилась @2. |
-901 | 336330755 | gbak_page_size_toobig |
Page size specified (@1) greater than limit (16384 bytes). Указанный размер страницы (@1) больше ограничения (16384 bytes). |
-901 | 335740932 | gfix_incmp_sw |
Incompatible switch combination. Несовместимая комбинация ключей командной строки. |
-901 | 336920580 | gstat_unexpected_eof |
Unexpected end of database file. Неожиданный конец файла базы данных. |
-901 | 336330756 | gbak_redir_ouput_missing |
Redirect location for output is not specified. Перенаправление места для вывода не указано. |
-901 | 336986116 | fbsvcmgr_info_err |
Unknown tag (@1) in info_svr_db_info block after isc_svc_query(). Неизвестный тег (@1) в блоке info_svr_db_info после вызова isc_svc_query(). |
-901 | 335740933 | gfix_replay_req |
Replay log pathname required. Воспроизведение лога требует пути до него. |
-901 | 336330757 | gbak_switches_conflict |
Conflicting switches for backup/restore. Конфликтующие операции командной строки для бекапа/рестора. |
-901 | 336986117 | fbsvcmgr_query_err |
Unknown tag (@1) in isc_svc_query() results. Неизвестный тег в результатах isc_svc_query(). |
-901 | 335544326 | bad_dpb_form |
Unrecognized database parameter block. Блок параметров базы данных не распознан. |
-901 | 335740934 | gfix_pgbuf_req |
Number of page buffers for cache required. Требуется указать количество страниц для буфера кэша. |
-901 | 336986118 | fbsvcmgr_switch_unknown |
Unknown switch "@1". Неизвестный параметр командной строки "@1". |
-901 | 336330758 | gbak_unknown_device |
Device type @1 not known. Тип устройства @1 не известен. |
-901 | 335544327 | bad_req_handle |
Invalid request handle. Неверный указатель запроса. |
-901 | 335740935 | gfix_val_req |
Numeric value required. Требуется числовое значение. |
-901 | 336330759 | gbak_no_protection |
Protection is not there yet. Опция «защита» еще не есть. |
-901 | 335544328 | bad_segstr_handle |
Invalid BLOB handle. Неверный указатель на BLOB. |
-901 | 335740936 | gfix_pval_req |
Positive numeric value required. Требуется положительное числовое значение. |
-901 | 336330760 | gbak_page_size_not_allowed |
Page size is allowed only on restore or create. Параметр «размер страницы» доступен только при восстановлении или создании. |
-901 | 335544329 | bad_segstr_id |
Invalid BLOB ID. Неверный ID BLOB. |
-901 | 335740937 | gfix_trn_req |
Number of transactions per sweep required. Требуется количество транзакция для операции sweep. |
-901 | 336330761 | gbak_multi_source_dest |
Multiple sources or destinations specified. Несколько источников или направлений указаны. |
-901 | 335544330 | bad_tpb_content |
Invalid parameter in transaction parameter block. Неверный параметр в блоке параметров транзакции. |
-901 | 336330762 | gbak_filename_missing |
Requires both input and output filenames. Требуются оба имени файла для ввода и для вывода. |
-901 | 335544331 | bad_tpb_form |
Invalid format for transaction parameter block. Неверный формат для блока параметров для транзакции. |
-901 | 336330763 | gbak_dup_inout_names |
Input and output have the same name. Disallowed. Ввод и вывод имеют одинаковое имя. Не разрешается. |
-901 | 335740940 | gfix_full_req |
"full" or "reserve" required. Параметры "full" или "reserve" требуются. |
-901 | 335544332 | bad_trans_handle |
Invalid transaction handle (expecting explicit transaction start). Неверная ссылка на транзакцию (ожидаю явного старта транзакций). |
-901 | 336330764 | gbak_inv_page_size |
Expected page size, encountered "@1". Ожидалось размер страницы, встретилось "@1". |
-901 | 335740941 | gfix_usrname_req |
User name required. Требуется имя пользователя. |
-901 | 336330765 | gbak_db_specified |
REPLACE specified, but the first file @1 is a database. Указан параметр ЗАМЕНА, но первый файл @1 является базой данных. |
-901 | 335740942 | gfix_pass_req |
Password required. Требуется пароль. |
-901 | 336330766 | gbak_db_exists |
Database @1 already exists.To replace it, use the -REP switch. База данных @1 уже существует. Чтобы заменить ее, используйте переключатель командной строки -REP. |
-901 | 335740943 | gfix_subs_name |
Subsystem name. Имя подсистемы. |
-901 | 336723983 | gsec_cant_open_db |
Unable to open database. Не могу открыть базу данных. |
-901 | 336330767 | gbak_unk_device |
Device type not specified. Тип устройства не указан. |
-901 | 336723984 | gsec_switches_error |
Error in switch specifications. Ошибка в указании опций командной строки. |
-901 | 335740945 | gfix_sec_req |
Number of seconds required. Число секунд требуется. |
-901 | 335544337 | excess_trans |
Attempt to start more than @1 transactions. Попытка начать более чем @1 транзакций. |
-901 | 336723985 | gsec_no_op_spec |
No operation specified. Операция не определена. |
-901 | 335740946 | gfix_nval_req |
Numeric value between 0 and 32767 inclusive required. Цифровое значение между 0 и 32767 включительно требуется. |
-901 | 336723986 | gsec_no_usr_name |
No user name specified. Не определено имя пользователя. |
-901 | 335740947 | gfix_type_shut |
Must specify type of shutdown. Требуется определить тип шатдауна. |
-901 | 335544339 | infinap |
Information type inappropriate for object specified. Тип данных подходит для указанного объекта. |
-901 | 336723987 | gsec_err_add |
Add record error. Ошибка добавления записи. |
-901 | 335544340 | infona |
No information of this type available for object specified. Нет информации этого типа доступной для указанного объекта. |
-901 | 336723988 | gsec_err_modify |
Modify record error. Ошибка изменения записи. |
-901 | 336330772 | gbak_blob_info_failed |
Gds_$blob_info failed. Операция Gds_$blob_info не удалась. |
-901 | 335740948 | gfix_retry |
Please retry, specifying an option. Пожалуйста повторите, уточните опцию. |
-901 | 335544341 | infunk |
Unknown information item. Незнакомый элемент информации. |
-901 | 336723989 | gsec_err_find_mod |
Find / modify record error. Ошибка поиска/изменения записи. |
-901 | 336330773 | gbak_unk_blob_item |
Do not understand BLOB INFO item @1. Не понятный элемент BLOB INFO @1. |
-901 | 335544342 | integ_fail |
Action cancelled by trigger (@1) to preserve data integrity. Действие отменено триггером (@1) чтобы сохранить целостность данных. |
-901 | 336330774 | gbak_get_seg_failed |
Gds_$get_segment failed. Операция Gds_$get_segment не удалась. |
-901 | 336723990 | gsec_err_rec_not_found |
Record not found for user: @1. Запись не найдена для пользователя: @1. |
-901 | 336723991 | gsec_err_delete |
Delete record error. Ошибка удаления записи. |
-901 | 336330775 | gbak_close_blob_failed |
Gds_$close_blob failed. Операция Gds_$close_blob не удалась. |
-901 | 335740951 | gfix_retry_db |
Please retry, giving a database name. Пожалуйста повторите, давая имя базы данных. |
-901 | 336330776 | gbak_open_blob_failed |
Gds_$open_blob failed. Операция Gds_$open_blob не удалась. |
-901 | 336723992 | gsec_err_find_del |
Find / delete record error. Ошибка поиска/удаления записи. |
-901 | 335544345 | lock_conflict |
Lock conflict on no wait transaction. Ошибка блокировки при не ждущей транзакции. |
-901 | 336330777 | gbak_put_blr_gen_id_failed |
Failed in put_blr_gen_id. Операция put_blr_gen_id не удалась. |
-901 | 336330778 | gbak_unk_type |
Data type @1 not understood. Тип данных @1 не понят. |
-901 | 336330779 | gbak_comp_req_failed |
Gds_$compile_request failed. Операция Gds_$compile_request не удалась. |
-901 | 336330780 | gbak_start_req_failed |
Gds_$start_request failed. Операция Gds_$start_request не удалась. |
-901 | 336723996 | gsec_err_find_disp |
Find / display record error. Ошибка в Найти/показать запись. |
-901 | 336330781 | gbak_rec_failed |
gds_$receive failed. Операция gds_$receive не удалась. |
-901 | 336920605 | gstat_open_err |
Can't open database file @1. Не могу открыть файл базы данных <строка>. |
-901 | 336723997 | gsec_inv_param |
Invalid parameter, no switch defined. Неверный параметр, нет ключа командной строки. |
-901 | 335544350 | no_finish |
Program attempted to exit without finishing database. Программа попыталась завершиться без отсоединения от базы данных. |
-901 | 336920606 | gstat_read_err |
Can't read a database page. Не могу прочитать страницу базы данных. |
-901 | 336330782 | gbak_rel_req_failed |
Gds_$release_request failed. Операция Gds_$release_request не удалась. |
-901 | 336723998 | gsec_op_specified |
Operation already specified. Операция уже определена. |
-901 | 336920607 | gstat_sysmemex |
System memory exhausted. Системная память исчерпана. |
-901 | 336330783 | gbak_db_info_failed |
gds_$database_info failed. Операция gds_$database_info не удалась. |
-901 | 336723999 | gsec_pw_specified |
Password already specified. Пароль уже определен. |
-901 | 336724000 | gsec_uid_specified |
Uid already specified. UID уже определен. |
-901 | 336330784 | gbak_no_db_desc |
Expected database description record. Ожидалась описание записи базы данных. |
-901 | 335544353 | no_recon |
Transaction is not in limbo. Транзакция не является limbo (не находится в подвешенном состоянии). |
-901 | 336724001 | gsec_gid_specified |
Gid already specified. GID уже указан. |
-901 | 336330785 | gbak_db_create_failed |
Failed to create database @1. Ошибка создания базы данных @1. |
-901 | 336724002 | gsec_proj_specified |
Project already specified. Параметр «проект» уже указан. |
-901 | 336330786 | gbak_decomp_len_error |
RESTORE: decompression length error. Восстановление: ошибка длины декомпрессии. |
-901 | 335544355 | no_segstr_close |
BLOB was not closed. BLOB был не закрытым. |
-901 | 336330787 | gbak_tbl_missing |
Cannot find table @1. Не могу найти таблицу @1. |
-901 | 336724003 | gsec_org_specified |
Organization already specified. Организация уже указана. |
-901 | 336330788 | gbak_blob_col_missing |
Cannot find column for BLOB. Не могу найти столбец для BLOB. |
-901 | 336724004 | gsec_fname_specified |
First name already specified. Параметр «имя» уже указано. |
-901 | 335544357 | open_trans |
Cannot disconnect database with open transactions (@1 active). Не могу отключить базу данных от открытых коннектов (@1 активных). |
-901 | 336330789 | gbak_create_blob_failed |
Gds_$create_blob failed. Операция Gds_$create_blob не удалась. |
-901 | 336724005 | gsec_mname_specified |
Middle name already specified. Второе имя (отчество) уже указано. |
-901 | 335544358 | port_len |
Message length error ( encountered @1, expected @2). Ошибка в длине сообщения ( встретилась @1, ожидалось @2). |
-901 | 336330790 | gbak_put_seg_failed |
Gds_$put_segment failed. Операция Gds_$put_segment не удалась. |
-901 | 336724006 | gsec_lname_specified |
Last name already specified. Фамилия уже указана. |
-901 | 336330791 | gbak_rec_len_exp |
Expected record length. Ошибка в ожидаемой длине записи. |
-901 | 336724008 | gsec_inv_switch |
Invalid switch specified. Неверный параметр командной строки указан. |
-901 | 336330792 | gbak_inv_rec_len |
Wrong length record, expected @1 encountered @2. Неверная длина записи, ожидалось @1, встретилась @2. |
-901 | 336330793 | gbak_exp_data_type |
Expected data attribute. Ожидаемый атрибут данных. |
-901 | 336724009 | gsec_amb_switch |
Ambiguous switch specified. Неоднозначный переключатель командной строки указан. |
-901 | 336330794 | gbak_gen_id_failed |
Failed in store_blr_gen_id. Ошибка в store_blr_gen_id. |
-901 | 336724010 | gsec_no_op_specified |
No operation specified for parameters. Нет операции указанной для параметров. |
-901 | 335544363 | req_no_trans |
No transaction for request. Нет транзакции для запроса. |
-901 | 336330795 | gbak_unk_rec_type |
Do not recognize record type @1. Не распознан тип записи @1. |
-901 | 336724011 | gsec_params_not_allowed |
No parameters allowed for this operation. Нет параметров доступных для этой операции. |
-901 | 335544364 | req_sync |
Request synchronization error. Ошибка синхронизации запроса. |
-901 | 336724012 | gsec_incompat_switch |
Incompatible switches specified. Указанные несовместимые переключатели командной строки. |
-901 | 336330796 | gbak_inv_bkup_ver |
Expected backup version 1..8. Found @1. Ожидалась версия бекапа в пределах 1..8. Обнаружена @1. |
-901 | 335544365 | req _ wrong _ db |
Request referenced an unavailable database. Запрос ссылается на недоступный базу данных. |
-901 | 336330 797 | gbak_missing_bkup_desc |
Expected backup description record. Ожидается описание бекапа. |
-901 | 336330798 | gbak_string_trunc |
String truncated. Усечение строки. |
-901 | 336330799 | gbak_cant_rest_record |
warning -- record could not be restored. Предупреждение – запись не может быть восстановлена. |
-901 | 336330800 | gbak_send_failed |
Gds_$send failed. Ошибка Gds_$send. |
-901 | 335544369 | segstr_no_read |
Attempted read of a new, open BLOB. Попытка чтения нового, а открыт BLOB. |
-901 | 336330801 | gbak_no_tbl_name |
No table name for data. Не указано имя таблицы для данных. |
-901 | 335544370 | segstr_no_trans |
Attempted action on blob outside transaction. Попытка действия на BLOB за пределами транзакции. |
-901 | 336330802 | gbak_unexp_eof |
Unexpected end of file on backup file. Неожиданный признак конца файла в файле бекапа. |
-901 | 336330803 | gbak_db_format_too_old |
Database format @1 is too old to restore to. Формат базы данных @1 слишком старый чтобы восстановить базу. |
-901 | 335544372 | segstr_wrong_db |
Attempted reference to BLOB in unavailable database. Попытка сослаться на BLOB в недоступной базе данных. |
-901 | 336330804 | gbak_inv_array_dim |
Array dimension for column @1 is invalid. Размерность массива для столбца @1 неверная. |
-901 | 336330807 | gbak_xdr_len_expected |
Expected XDR record length. Ожидаемая длина записи XDR. |
-901 | 335544376 | unres_rel |
Table @1 was omitted from the transaction reserving list. Таблица @1 была исключена из списка резервирования транзакций. |
-901 | 335544377 | uns_ext |
Request includes a DSRI extension not supported in this implementation. Запрос включает в себя расширение DSRI не поддерживается в этой реализации. |
-901 | 335544378 | wish_list |
Feature is not supported. Опция не поддерживается. |
-901 | 335544382 | random | @1 |
-901 | 335544383 | fatal_conflict |
Unrecoverable conflict with limbo transaction @1. Неустранимый конфликт с лимбо транзакцией @1. |
-901 | 335740991 | gfix_exceed_max |
Internal block exceeds maximum size. Внутренний блок превышает максимальный размер. |
-901 | 335740992 | gfix_corrupt_pool |
Corrupt pool. Разрушение пула. |
-901 | 335740993 | gfix_mem_exhausted |
Virtual memory exhausted. Виртуальная память исчерпана. |
-901 | 336330817 | gbak_open_bkup_error |
Cannot open backup file @1. Не могу открыть файл бекапа @1. |
-901 | 335740994 | gfix_bad_pool |
Bad pool id. Неверный ID пула. |
-901 | 336330818 | gbak_open_error |
Cannot open status and error output file @1. Не могу получить статус и произошла ошибка выходного файла <строка>. |
-901 | 335740995 | gfix_trn_not_valid |
Transaction state @1 not in valid range. Состояние транзакции <число> вне пределах верного диапазона. |
-901 | 335544392 | bdbincon |
Internal error. Внутренняя ошибка. |
-901 | 336724044 | gsec_inv_username |
Invalid user name (maximum 31 bytes allowed). Неверное имя пользователя. (максимум 31 байт доступен). |
-901 | 336724045 | gsec_inv_pw_length |
Warning - maximum 8 significant bytes of password used. Внимание – максимум 8 значащих байт для пароля используется. |
-901 | 336724046 | gsec_db_specified |
Database already specified. База данных уже указана. |
-901 | 336724047 | gsec_db_admin_specified |
Database administrator name already specified. Имя администратора базы данных уже указано. |
-901 | 336724048 | gsec_db_admin_pw_specified |
Database administrator password already specified. Пароль администратора базы данных уже указан. |
-901 | 336724049 | gsec_sql_role_specified |
SQL role name already specified Имя SQL роли уже указаны |
-901 | 335741012 | gfix_unexp_eoi |
Unexpected end of input Неожиданных конец ввода |
-901 | 335544407 | dbbnotzer |
Database handle not zero Указатель базы данных не ноль |
-901 | 335544408 | tranotzer |
Transaction handle not zero Указатель транзакции не ноль |
-901 | 335741018 | gfix_recon_fail |
Failed to reconnect to a transaction in database @1 Сбой реконнекта транзакции в базе данных < строка > |
-901 | 335544418 | trainlim |
Transaction in limbo Транзакция в лимбо (зависла) |
-901 | 335544419 | notinlim |
Transaction not in limbo Транзакция не в лимбо ( зависла ) |
-901 | 335544420 | traoutsta |
Transaction outstanding Транзакция выдалась за пределы |
-901 | 335544428 | badmsgnum |
Undefined message number Неопределенный номер сообщения |
-901 | 335741036 | gfix_trn_unknown |
Transaction description item unknown Элемент описания транзакции неизвестен |
-901 | 335741038 | gfix_mode_req |
"read_only" or "read_write" required Требуются параметры "read_only" или "read_write" |
-901 | 335544431 | blocking_signal |
Blocking signal has been received Был получен блокирующий сигнал |
-901 | 335741042 | gfix_pzval_req |
Positive or zero numeric value required Требуется положительное или нулевое значение |
-901 | 335544442 | noargacc_read |
Database system cannot read argument @1 СУБД не может прочитать аргумент <строка> |
-901 | 335544443 | noargacc_write |
Database system cannot write argument @1 СУБД не может записать аргумент < строка > |
-901 | 335544450 | misc_interpreted | @1 |
-901 | 335544468 | tra_state |
Transaction @1 is @2 Транзакция <строка> является <строка> |
-901 | 335544485 | bad_stmt_handle |
Invalid statement handle Неверный указатель выражения |
-901 | 336330934 | gbak_missing_block_fac |
Blocking factor parameter missing Параметр blocking factor отсутствует |
-901 | 336330935 | gbak_inv_block_fac |
Expected blocking factor, encountered "@1" Ожидался Blocking factor, встретилось < строка > |
-901 | 336330936 | gbak_block_fac_specified |
A blocking factor may not be used in conjunction with device CT Blocking factor не могут быть использованы в сочетании с устройством CT |
-901 | 336068796 | dyn_role_does_not_exist |
SQL role @1 does not exist SQL роль <строка> не существует |
-901 | 336330940 | gbak_missing_username |
User name parameter missing Параметр имя пользователя отсутствует |
-901 | 336330941 | gbak_missing_password |
Password parameter missing Параметр пароль отсутствует |
-901 | 336068797 | dyn_no_grant_admin_opt |
User @1 has no grant admin option on SQL role @2 Пользователь < строка > не имеет администраторской опции GRANT в SQL роли < строка > |
-901 | 335544510 | lock_timeout |
Lock time - out on wait transaction В ждущей транзакции произошел тайм-аут блокировки |
-901 | 336068798 | dyn_user_not_role_member |
User @1 is not a member of SQL role @2 Пользователь < строка > не является членом SQL роли |
-901 | 336068799 | dyn_delete_role_failed |
@1 is not the owner of SQL role @2 < строка > не принадлежит SQL роли < строка > |
-901 | 336068800 | dyn_grant_role_to_user |
@1 is a SQL role and not a user <строка> является SQL ролью, а не пользователем |
-901 | 336068801 | dyn_inv_sql_role_name |
User name @1 could not be used for SQL role Имя пользователя не может использоваться для названия SQL роли |
-901 | 336068802 | dyn_dup_sql_role |
SQL role @1 already exists SQL роль <строка> уже существует |
-901 | 336068803 | dyn_kywd_spec_for_role |
Keyword @1 can not be used as a SQL role name Ключевое слово <строка> не может быть использовано в качестве имени роли |
-901 | 336068804 | dyn_roles_not_supported |
SQL roles are not supported in on older versions of the database.A backup and restore of the database is required. SQL роль не поддерживается в более старых версиях СУБД. Требуется выполнить операцию бекап – рестор для базы данных. |
-901 | 336330952 | gbak_missing_skipped_bytes |
missing parameter for the number of bytes to be skipped Отсутствующий параметр для количества байт был обойден |
-901 | 336330953 | gbak_inv_skipped_bytes |
Expected number of bytes to be skipped, encountered "@1" Ожидалось число байтов для пропуска, встретилось "@1" |
-901 | 336068820 | dyn_zero_len_id |
Zero length identifiers are not allowed Идентификаторы с нулевой длиной не допускаются |
-901 | 336330965 | gbak_err_restore_charset |
Character set Ошибка при восстановлении: Character set |
-901 | 336330967 | gbak_err_restore_collation |
Collation Ошибка при восстановлении: Collation |
-901 | 336330972 | gbak_read_error |
Unexpected I/O error while reading from backup file Неожиданная ошибка операции ввода – вывода при чтении файла бекапа |
-901 | 336330973 | gbak_write_error |
Unexpected I/O error while writing to backup file Неожиданная ошибка операции ввода – вывода при записи файла бекапа |
-901 | 336068840 | dyn_wrong_gtt_scope |
@1 cannot reference @2 @1 не может ссылаться на @2 |
-901 | 336330985 | gbak_db_in_use |
Could not drop database @1 (database might be in use) Не могу удалить базу данных @1 (операция DROP ) (база данных может использоваться) |
-901 | 336330990 | gbak_sysmemex |
System memory exhausted Системная память исчерпана |
-901 | 335544559 | bad_svc_handle |
Invalid service handle Неверный дескриптор службы |
-901 | 335544561 | wrospbver |
Wrong version of service parameter block Неверная версия блока параметров сервиса |
-901 | 335544562 | bad_spb_form |
Unrecognized service parameter block Не распознан блок параметров сервиса |
-901 | 335544563 | svcnotdef |
Service @1 is not defined Сервис @1 не определен |
-901 | 336068856 | dyn_ods_not_supp_feature |
Feature '@1' is not supported in ODS @2.@3 Возможность '@1' не поддерживается в ODS @2.@3 |
-901 | 336331002 | gbak_restore_role_failed |
SQL role Ошибка восстановления SQL роли |
-901 | 336331005 | gbak_role_op_missing |
SQL role parameter missing Параметр SQL роль отсутствует |
-901 | 336331010 | gbak_page_buffers_missing |
Page buffers parameter missing Параметр Page buffers отсутствует |
-901 | 336331011 | gbak_page_buffers_wrong_param |
Expected page buffers, encountered "@1" Ожидался параметр page buffers, встретилось @1 |
-901 | 336331012 | gbak_page_buffers_restore |
Page buffers is allowed only on restore or create Параметр page buffers позволяет только восстановить или создать |
-901 | 336331014 | gbak_inv_size |
Size specification either missing or incorrect for file @1 Размер спецификации или отсутствует или некорректный для файла @1 |
-901 | 336331015 | gbak_file_outof_sequence |
File @1 out of sequence Файл @1 выпал из последовательности |
-901 | 336331016 | gbak_join_file_missing |
Can't join - one of the files missing Не могу соединить – один из файлов отсутствует |
-901 | 336331017 | gbak_stdin_not_supptd |
standard input is not supported when using join operation Поток stdin не поддерживается при использование операции «соединить» (join) |
-901 | 336331018 | gbak_stdout_not_supptd |
Standard output is not supported when using split operation Поток stdout не поддерживается при использование операции "разделить" (split) |
-901 | 336331019 | gbak_bkup_corrupt |
Backup file @1 might be corrupt Файл бэкапа <строка> может быть поврежден |
-901 | 336331020 | gbak_unk_db_file_spec |
Database file specification missing Файл спецификации базы данных отсутствует |
-901 | 336331021 | gbak_hdr_write_failed |
Can't write a header record to file @1 Не могут записать заголовок в файл @1 |
-901 | 336331022 | gbak_disk_space_ex |
Free disk space exhausted Свободное место на диске исчерпано |
-901 | 336331023 | gbak_size_lt_min |
File size given (@1) is less than minimum allowed (@2) Размер файла дан (@1) – является меньшим чем минимально допущенный (@2) |
-901 | 336331025 | gbak_svc_name_missing |
Service name parameter missing Параметр имя службы отсутствует |
-901 | 336331026 | gbak_not_ownr |
Cannot restore over current database, must be SYSDBA or owner of the existing database. Не могу восстановить поверх текущей базы данных, должен быть SYSDBA или владелец существующей базы данных. |
-901 | 336331031 | gbak_mode_req |
"read_only" or "read_write" required Требуются режимы "read_only" или "read_write" |
-901 | 336331033 | gbak_just_data |
Just data ignore all constraints etc. Только данные, игнорируя все условия контроля целостности данных |
-901 | 336331034 | gbak_data_only |
Restoring data only ignoring foreign key, unique, not null & other constraints Режим восстановления «только данные» игнорирующий все ограничения по внешним ключам, условиям уникальности данных, NOT NULL и прочим условиям проверки целостности данных |
-901 | 335544609 | index_name | INDEX @1 |
-901 | 335544610 | exception_name | EXCEPTION @1 |
-901 | 335544611 | field_name | COLUMN @1 |
-901 | 335544613 | union_err |
Union not supported Операция UNION не поддерживается |
-901 | 335544614 | dsql_construct_err |
Unsupported DSQL construct Не поддерживаемая конструкция DSQL |
-901 | 335544623 | dsql_domain_err |
Illegal use of keyword VALUE Неверное использование слова VALUE |
-901 | 335544626 | table_name | TABLE @1 |
-901 | 335544627 | proc_name | PROCEDURE @1 |
-901 | 335544641 | dsql_domain_not_found |
Specified domain or source column @1 does not exist Указанный домен или столбец – источник @1 не существует |
-901 | 335544656 | dsql_var_conflict |
Variable @1 conflicts with parameter in same procedure Переменная @1 конфликтует с одноименным параметром в процедуре |
-901 | 335544666 | srvr_version_too_old |
Server version too old to support all CREATE DATABASE options Слишком старая версия сервера чтобы поддерживать все опции команды CREATE DATABASE |
-901 | 335544673 | no_delete |
Cannot delete Не могу удалить |
-901 | 335544675 | sort_err |
Sort error Ошибка сортировки |
-901 | 335544703 | svcnoexe |
Service @1 does not have an associated executable Сервис @1 не имеет связанного исполнителя |
-901 | 335544704 | net_lookup_err |
Failed to locate host machine. Не удалось найти хост машины |
-901 | 335544705 | service_unknown |
Undefined service @1/@2. Неопределенная служба @1/@2. |
-901 | 335544706 | host_unknown |
The specified name was not found in the hosts file or Domain Name Services. Указанное имя не найдено в файле hosts или в DNS. |
-901 | 335544711 | unprepared_stmt |
Attempt to execute an unprepared dynamic SQL statement. Попытка выполнить неподготовленный DSQL запрос. |
-901 | 335544716 | svc_in_use |
Service is currently busy: @1 Сервис в настоящий момент занят: @1 |
-901 | 335544731 | tra_must_sweep | |
-901 | 335544740 | udf_exception |
A fatal exception occurred during the execution of a user defined function. Фатальное исключение произошло во время выполнения UDF. |
-901 | 335544741 | lost_db_connection |
Connection lost to database Соединение с базой данных потеряно |
-901 | 335544742 | no_write_user_priv |
User cannot write to RDB$USER_PRIVILEGES Пользователь не может писать в таблицу RDB$USER_PRIVILEGES |
-901 | 335544767 | blob_filter_exception |
A fatal exception occurred during the execution of a blob filter. Фатальное исключение произошло во время исполнения BLOB фильтра. |
-901 | 335544768 | exception_access_violation |
Access violation.The code attempted to access a virtual address without privilege to do so. Ошибка доступа. Код попытался получить доступ к виртуальному адресу без соответствующих привилегий на это. |
-901 | 335544769 | exception_datatype_missalignment |
Datatype misalignment.The attempted to read or write a value that was not stored on a memory boundary. Тип данных не выровнен. Попытка прочитать или записать значение, которое не хранится в границах области памяти. |
-901 | 335544770 | exception_array_bounds_exceeded |
Array bounds exceeded. The code attempted to access an array element that is out of bounds. Превышение границ массива. Код пытался получить доступ к элементам массива за его пределами. |
-901 | 335544771 | exception_float_denormal_ operan d |
Float denormal operand.One of the floating-point operands is too small to represent a standard float value. Аномальное число с плавающей точкой. Один из операндов с плавающей точкой слишком мал, чтобы представить стандартным значением с плавающей точкой. |
-901 | 335544772 | exception_float_divide_by_zero |
Floating-point divide by zero.The code attempted to divide a floating-point value by zero. Числа с плавающей точкой; деление на ноль. Код попытался выполнить деление числа с плавающей точкой на ноль. |
-901 | 335544773 | exception_float_inexact_result |
Floating-point inexact result.The result of a floating-point operation cannot be represented as a decimal fraction. Числа с плавающей точкой; неточный результат. Результат операции с плавающей точкой не может быть представлен в виде десятичной дроби. |
-901 | 335544774 | exception _float_invalid_operand |
Floating-point invalid operand.An indeterminant error occurred during a floating-point operation. Числа с плавающей точкой; неверная операция. Неопределяемая ошибка произошла во время операций с плавающей точкой. |
-901 | 335544775 | exception_float_overflow |
Floating-point overflow.The exponent of a floating-point operation is greater than the magnitude allowed. Числа с плавающей точкой; переполнение. Показатель операции с плавающей точкой больше, чем допустимая величина. |
-901 | 335544776 | exception_float_stack_check |
Floating-point stack check.The stack overflowed or underflowed as the result of a floating-point operation. Числа с плавающей точкой; проверка стека. Стек переполнен или показатель операции с плавающей точкой меньше величины допустимого, в результате операции с плавающей точкой. |
-901 | 335544777 | exception_float_underflow |
Floating-point underflow.The exponent of a floating-point operation is less than the magnitude allowed. Числа с плавающей точкой. Показатель операции с плавающей точкой меньше величины допустимого. |
-901 | 335544778 | exception_integer_divide_by_zero |
Integer divide by zero.The code attempted to divide an integer value by an integer divisor of zero. Целые числа; деление на ноль. Код попытался выполнить операцию целочисленного деления целого числа на ноль. |
-901 | 335544779 | exception_integer_overflow |
Integer overflow.The result of an integer operation caused the most significant bit of the result to carry. Переполнение целого числа. В результате операций с целыми числами был выставлен самый старший бит, отвечающий за перенос. |
-901 | 335544780 | exception_unknown |
An exception occurred that does not have a description.Exception number @1. Произошло исключение, но оно не имеет описания. Номер исключения @1. |
-901 | 335544781 | exception_stack_overflow |
Stack overflow.The resource requirements of the runtime stack have exceeded the memory available to it. Переполнение стека. Требования ресурсов к операциях к стеку превысили память отведенную под него. |
-901 | 335544782 | exception_sigsegv |
Segmentation Fault. The code attempted to access memory without priviledges. Ошибка сегментации. Код попытался получить доступ к области памяти без соответствующих привилегий. |
-901 | 335544783 | exception_sigill |
Illegal Instruction. The Code attempted to perfrom an illegal operation. Неверная инструкция. Код попытался выполнить нелегальную операцию. |
-901 | 335544784 | exception_sigbus |
Bus Error. The Code caused a system bus error. Ошибка шины. Код вызвал системную ошибку шины. |
-901 | 335544785 | exception_sigfpe |
Floating Point Error. The Code caused an Arithmetic Exception or a floating point exception. Ошибка операции с плавающей точкой. Код вызвал арифметическое исключение или исключение операций с плавающей точкой. |
-901 | 335544786 | ext_file_delete |
Cannot delete rows from external files. Невозможно удалить строки из внешних таблиц/файлов |
-901 | 335544787 | ext_file_modify |
Cannot update rows in external files. Не могут обновлять строки во внешних файлах. |
-901 | 335544788 | adm_task_denied |
Unable to perform operation.You must be either SYSDBA or owner of the database Не могу выполнить операцию. Вы должны быть SYSDBA или владельцем базы данных. |
-901 | 335544794 | cancelled |
Operation was cancelled Операция была отменена |
-901 | 335544797 | svcnouser |
User name and password are required while attaching to the services manager Для доступа к менеджеру сервисов требуется имя пользователя и пароль |
-901 | 335544801 | datype_notsup |
Data type not supported for arithmetic Тип данных не поддерживается для арифметических операций |
-901 | 335544803 | dialect_not_changed |
Database dialect not changed. Диалект базы данных не изменен. |
-9 01 | 335544804 | database_create_failed |
Unable to create database @1 Не могу создать базу данных @1 |
-901 | 335544805 | inv_dialect_specified |
Database dialect @1 is not a valid dialect. Диалект базы данных @1 не является верным диалектом |
-901 | 335544806 | valid_db_dialects |
Valid database dialects are @1. Верным диалектом базы данных является @1. |
-901 | 335544811 | inv_client_dialect_specified |
Passed client dialect @1 is not a valid dialect. Переданный клиентской программой диалект @1 не является верным диалектом |
-901 | 335544812 | valid_client_dialects |
Valid client dialects are @1. Верным клиентским диалектом является @1. |
-901 | 335544814 | service_not_supported |
Services functionality will be supported in a later versionof the product Функциональность сервисов будет поддерживаться в дальнейших версиях продукта |
-901 | 335544820 | invalid_savepoint |
Unable to find savepoint with name @1 in transaction context Не могу найти точку сохранения транзакции с именем @1 в контексте транзакции |
-901 | 335544835 | bad_shutdown_mode |
Target shutdown mode is invalid for database "@1" Указание режима «шатдаун» неверное для базы данных "@1" |
-901 | 335544840 | no_update |
Cannot update Не могу обновить |
-901 | 335544842 | stack_trace | @1 |
-901 | 335544843 | ctx_var_not_found |
Context variable @1 is not found in namespace @2 Контекстная переменная @1 не найдена в пространстве имен @2 |
-901 | 335544844 | ctx_namespace_invalid |
Invalid namespace name @1 passed to @2 Неверное имя пространства имен @1 передается в @2 |
-901 | 335544845 | ctx_too_big |
Too many context variables Слишком много контекстных переменных |
-901 | 335544846 | ctx_bad_argument |
Invalid argument passed to @1 Неверный аргумент передан в @1 |
-901 | 335544847 | identifier_too_long |
BLR syntax error. Identifier @1... is too long Ошибка синтаксиса BLR. Идентификатор @1 является слишком большим |
-901 | 335544859 | invalid_time_precision |
Time precision exceeds allowed range (0-@1) Уровень точности времени (тип данных TIME ) превышает допустимый диапазон (0 - @1) |
-901 | 335544866 | met_wrong_gtt_scope |
@1 cannot depend on @2 <строка> не может зависеть от <строка> |
-901 | 335544868 | illegal_prc_type |
Procedure @1 is not selectable (it does not contain a SUSPEND statement) Процедура @1 не является процедурой выборки ( она не содержит оператор SUSPEND) |
-901 | 335544869 | invalid_sort_datatype |
Datatype @1 is not supported for sorting operation Тип данных @1 не поддерживается для операции сортировка |
-901 | 335544870 | collation_name |
COLLATION @1 Порядок сортировки @1 |
-901 | 335544871 | domain_name |
DOMAIN @1 ДОМЕН @1 |
-901 | 335544874 | max_db_per_trans_allowed |
A multi database transaction cannot span more than @1 databases Мультибазовая транзакция не может занимать более чем @1 баз данных |
-901 | 335544876 | bad_proc_BLR |
Error while parsing procedure @1' s BLR Ошибка во время разбора BLR процедуры @1 |
-901 | 335544877 | key_too_big |
Index key too big Ключ индекса слишком велик |
-901 | 336397211 | dsql_too_many_values |
Too many values ( more than @1) in member list to match against Слишком много значений (более чем @1) в списке членов, чтобы соответствовать против |
-901 | 336397236 | dsql_unsupp_feature_dialect |
Feature is not supported in dialect @1 Особенность не поддерживается в диалекте @1 |
-902 | 335544333 | bug_check |
Internal gds software consistency check (@1) Внутренняя проверка целостности программного обеспечения (@1) |
-902 | 335544335 | db_corrupt |
Database file appears corrupt (@1) Файл базы данных является поврежденным (@1) |
-902 | 335544344 | io_error |
I/O error for file "@2" Ошибка ввода – вывода для файла @1 |
-902 | 335544346 | metadata_corrupt |
Corrupt system table Повреждение системной таблицы |
-902 | 335544373 | sys_request |
Operating system directive @1 failed Директива операционной системы @1 не удалась |
-902 | 335544384 | badblk |
Internal error Внутренняя ошибка |
-902 | 335544385 | invpoolcl |
Internal error Внутренняя ошибка |
-902 | 335544387 | relbadblk |
Internal error Внутренняя ошибка |
-902 | 335544388 | blktoobig |
Block size exceeds implementation restriction Размер блока превышает ограничение реализации |
-902 | 335544394 | badodsver |
Incompatible version of on-disk structure Несовместимая версия ODS |
-902 | 335544397 | dirtypage |
Internal error Внутренняя ошибка |
-902 | 335544398 | waifortra |
Internal error Внутренняя ошибка |
-902 | 335544399 | doubleloc |
Internal error Внутренняя ошибка |
-902 | 335544400 | nodnotfnd |
Internal error Внутренняя ошибка |
-902 | 335544401 | dupnodfnd |
Internal error Внутренняя ошибка |
-902 | 335544402 | locnotmar |
Internal error Внутренняя ошибка |
-902 | 335544404 | corrupt |
Database corrupted База данных повреждена |
-902 | 335544405 | badpage |
Checksum error on database page @1 Ошибка контрольной суммы на странице базы данных @1 |
-902 | 335544406 | badindex |
Index is broken Индекс поврежден |
-902 | 335544409 | trareqmis |
Transaction -- request mismatch ( synchronization error ) Транзакция – несоответствие запроса (ошибка синхронизации) |
-902 | 335544410 | badhndcnt |
Bad handle count Неверный счетчик указателей |
-902 | 335544411 | wrotpbver |
Wrong version of transaction parameter block Неверная версия блока параметров транзакции |
-902 | 335544412 | wroblrver |
Unsupported BLR version (expected @1, encountered @2) Не поддерживаемая версия BLR ( ожидается @1 встретилась @2) |
-902 | 335544413 | wrodpbver |
Wrong version of database parameter block Неверная версия блока параметров базы данных |
-902 | 335544415 | badrelation |
Database corrupted База данных разрушена |
-902 | 335544416 | nodetach |
Internal error Внутренняя ошибка |
-902 | 335544417 | notremote |
Internal error Внутренняя ошибка |
-902 | 335544422 | dbfile |
Internal error Внутренняя ошибка |
-902 | 335544423 | orphan |
Internal error Внутренняя ошибка |
-902 | 335544432 | lockmanerr |
Lock manager error Ошибка менеджера блокировок |
-902 | 335544436 | sqlerr |
SQL error code = @1 SQL ошибка код = @1 |
-902 | 335544448 | bad_sec_info | |
-902 | 335544449 | invalid_sec_info | |
-902 | 335544470 | buf_invalid |
Cache buffer for page @1 invalid Буфер КЭШа для страницы @1 неверный |
-902 | 335544471 | indexnotdefined |
There is no index in table @1 with id @2 Не существует индекса в таблице @1 с идентификатором @2 |
-902 | 335544472 | login |
Your user name and password are not defined. Ask your database administrator to set up a Firebird login. Ваши имя и пароль не определены. Чтобы установить соединение с Firebird обратитесь к администратору базы данных. |
-902 | 335544506 | shutinprog |
Database @1 shutdown in progress Выполняется останов (shutdown) базы данных @1 |
-902 | 335544528 | shutdown |
Database @1 shutdown База данных @1 в режиме «шатдаун» |
-902 | 335544557 | shutfail |
Database shutdown unsuccessful Не успешный шатдаун базы данных |
-902 | 335544569 | dsql_error |
Dynamic SQL Error Ошибка динамического SQL |
-902 | 335544653 | psw_attach |
Cannot attach to password database Невозможно соединиться с базой данных с этим паролем |
-902 | 335544654 | psw_start_trans |
Cannot start transaction for password database Невозможно стартовать транзакцию для базы данных пароля |
-902 | 335544717 | err_stack_limit |
Stack size insufficent to execute current request Размер стека недостаточен для выполнения текущего запроса |
-902 | 335544721 | network_error |
Unable to complete network request to host "@1". Невозможно завершить сетевой запрос на хост "@1" |
-902 | 335544722 | net_connect_err |
Failed to establish a connection. Ошибка при установлении соединения |
-902 | 335544723 | net_connect_listen_err |
Error while listening for an incoming connection. Ошибка при прослушивании входного соединения |
-902 | 335544724 | net_event_connect_err |
Failed to establish a secondary connection for event processing. Ошибка при установлении вторичного соединения для обработки события |
-902 | 335544725 | net_event_listen_err |
Error while listening for an incoming event connection request. Ошибка при прослушивании входного запроса для события соединения |
-902 | 335544726 | net_read_err |
Error reading data from the connection. Ошибка чтения данных из соединения |
-902 | 335544727 | net_write_err |
Error writing data to the connection. Ошибка записи данных в соединение |
-902 | 335544732 | unsupported_network_drive |
Access to databases on file servers is not supported. Доступ к базам данных в файловых серверах не поддерживается |
-902 | 335544733 | io_create_err |
Error while trying to create file Ошибка ввода-вывода при попытке создания файла |
-902 | 335544734 | io_open_err |
Error while trying to open file Ошибка ввода-вывода при попытке открытия файла |
-902 | 335544735 | io_close_err |
Error while trying to close file Ошибка ввода-вывода при попытке закрытия файла |
-902 | 335544736 | io_read_err |
Error while trying to read from file Ошибка ввода-вывода при попытке чтения из файла |
-902 | 335544737 | io_write_err |
Error while trying to write to file Ошибка ввода-вывода при попытке записи в файл |
-902 | 335544738 | io_delete_err |
Error while trying to delete file Ошибка ввода-вывода при попытке удаления файла |
-902 | 335544739 | io_access_err |
Error while trying to access file Ошибка ввода-вывода при попытке доступа к файлу |
-902 | 335544745 | login_same_as_role_name |
Your login @1 is same as one of the SQL role name. Ask your database administrator to set up a valid Firebird login. Ваше регистрационное имя @1 то же, что и имя роли SQL. Уточните у вашего администратора базы данных допустимое регистрационное имя Firebird. |
-902 | 335544791 | file_in_use |
The file @1 is currently in use by another process.Try again later. Файл @1 в настоящее время используется другим процессом. Попытайтесь позже. |
-902 | 335544795 | unexp_spb_form |
Unexpected item in service parameter block, expected @1 Неопределенный элемент в блоке параметров сервиса, ожидается @1 |
-902 | 335544809 | extern_func_dir_error |
Function @1 is in @2, which is not in a permitted directory for external functions. Функция @1 находится в @2, что не является доступным каталогом для внешних функций. |
-902 | 335544819 | io_32bit_exceeded_err |
File exceeded maximum size of 2GB. Add another database file or use a 64 bit I/O version of Firebird. Файл превысил максимальный размер 2 Гбайт. Добавьте другой файл базы данных или используйте 64битовую версию Firebird. |
-902 | 335544831 | conf_access_denied |
Access to @1 "@2" is denied by server administrator Доступ к @1 "@2" отвергнут администратором сервера |
-902 | 335544834 | cursor_not_open |
Cursor is not open Курсор не открыт |
-902 | 335544841 | cursor_already_open |
Cursor is already open Курсор уже открыт |
-902 | 335544856 | att_shutdown |
Connection shutdown Соединение остановлено |
-902 | 335544882 | long_login |
Login name too long (@1 characters, maximum allowed @2) Наименование логина слишком велико (@1 символов, максимально возможно @2) |
-904 | 335544324 | bad_db_handle |
Invalid database handle (no active connection) Указатель базы данных неверный (нет активного соединения) |
-904 | 335544375 | unavailable |
Unavailable database Недоступная база данных |
-904 | 335544381 | imp_exc |
Implementation limit exceeded Исчерпан лимит выполнения |
-904 | 335544386 | nopoolids |
Too many requests Слишком много запросов |
-904 | 335544389 | bufexh |
Buffer exhausted Исчерпан буфер |
-904 | 335544391 | bufinuse |
Buffer in use Буфер используется |
-904 | 335544393 | reqinuse |
Request in use Запрос используется |
-904 | 335544424 | no_lock_mgr |
No lock manager available Нет доступного менеджера блокировок |
-904 | 335544430 | virmemexh |
Unable to allocate memory from operating system Невозможно выделить память в операционной системе |
-904 | 335544451 | update_conflict |
Update conflicts with concurrent update Изменение конфликтует с конкурирующим обновлением |
-904 | 335544453 | obj_in_use |
Object @1 is in use Объект @1 используется |
-904 | 335544455 | shadow_accessed |
Cannot attach active shadow file Невозможно соединиться с активным файлом теневой копии |
-904 | 335544460 | shadow_missing |
A file in manual shadow @1 is unavailable Файл в ручной теневой копии @1 недоступен |
-904 | 335544661 | index_root_page_full |
Cannot add index, index root page is full. Невозможно добавить индекс, корневая страница индексов заполнена |
-904 | 335544676 | sort_mem_err |
Sort error: not enough memory Ошибка сортировки: недостаточно памяти |
-904 | 335544683 | req_depth_exceeded |
Request depth exceeded. (Recursive definition?) Превышена глубина запроса (рекурсивное определение?) |
-904 | 335544758 | sort_rec_size_err |
Sort record size of @1 bytes is too big байт Размер записи сортировки в @1 байт слишком велик |
-904 | 335544761 | too_many_handles |
Too many open handles to database Слишком много открыто дескрипторов базы данных |
-904 | 335544792 | service_att_err |
Cannot attach to services manager Не могу подключиться к менеджеру сервисов |
-904 | 335544799 | svc_name_missing |
The service name was not specified. Не указано имя сервиса |
-904 | 335544813 | optimizer_between_err |
Unsupported field type specified in BETWEEN predicate. Указан не поддерживаемый тип поля в предикате BETWEEN |
-904 | 335544827 | exec_sql_invalid_arg |
Invalid argument in EXECUTE STATEMENT-cannot convert to string Неверный аргумент в EXECUTE STATEMENT – невозможно конвертировать в строку |
-904 | 335544828 | exec_sql_invalid_req |
Wrong request type in EXECUTE STATEMENT '@1' Неверный тип запроса в EXECUTE STATEMENT '@1' |
-904 | 335544829 | exec_sql_invalid_var |
Variable type (position @1) in EXECUTE STATEMENT '@2' INTO does not match returned column type Тип переменной ( позиция @1) в EXECUTE STATEMENT '@2' INTO не соответствует возвращаемому типу столбца |
-904 | 335544830 | exec_sql_max_call_exceeded |
Too many recursion levels of EXECUTE STATEMENT Слишком много уровней рекурсии в EXECUTE STATEMENT |
-904 | 335544832 | wrong_backup_state |
Cannot change difference file name while database is in backup mode Не могу изменить файл – разницу пока база данных находится в режиме бекапа |
-904 | 335544852 | partner_idx_incompat_type |
Partner index segment no @1 has incompatible data type Сегмент @1 индекса – партнера содержит не совместимый тип данных |
-904 | 335544857 | blobtoobig |
Maximum BLOB size exceeded Достигнут максимальный размер BLOB |
-904 | 335544862 | record_lock_not_supp |
Stream does not support record locking Поток не поддерживает блокировку записей. |
-904 | 335544863 | partner_idx_not_found |
Cannot create foreign key constraint @1. Partner index does not exist or is inactive. Не могу создать конструкцию внешнего ключа. Индекс-партнер не существует или является неактивным. |
-904 | 335544864 | tra_num_exc |
Transactions count exceeded. Perform backup and restore to make database operable again Превышено число допустимых транзакций. Выполнение бекапа и рестор сделает вновь базу данных работоспособной. |
-904 | 335544865 | field_disappeared |
Column has been unexpectedly deleted Столбец был неожиданно удален |
-904 | 335544878 | concurrent_transaction |
Concurrent transaction number is @1 Число конкурирующих транзакций @1 |
-906 | 335544744 | max_att_exceeded |
Maximum user count exceeded.Contact your database administrator. Превышен максимум счетчика пользователей. Свяжитесь с вашим администратором базы данных. |
-909 | 335544667 | drdb _ completed _ with _ errs |
Drop database completed with errors Удаление базы данных завершилось с ошибками |
-911 | 335544459 | rec_in_limbo |
Record from transaction @1 is stuck in limbo Запись транзакции @1 становится зависшей |
-913 | 335544336 | Deadlock |
Deadlock Взаимная блокировка |
-922 | 335544323 | bad_db_format |
File @1 is not a valid database Файл @1 не является допустимой базой данных |
-923 | 335544421 | connect_reject |
Connection rejected by remote interface Соединение отменено удаленным интерфейсом |
-923 | 335544461 | cant_validate |
Secondary server attachments cannot validate databases Вторичные подключения к серверу не могут проверять базу данных |
-923 | 335544464 | cant_start_logging |
Secondary server attachments cannot start logging Вторичные подключения к серверу не могут начинать логгирование |
-924 | 335544325 | bad_dpb_content |
Bad parameters on attach or create database Неверные параметры при подключении или создании базы данных |
-924 | 335544441 | bad_detach |
Database detach completed with errors Отключение от базы данных завершилось с ошибками |
-924 | 335544648 | conn_lost |
Connection lost to pipe server Потеря соединения с каналом сервера |
-926 | 335544447 | no_rollback |
No rollback performed Не выполнен откат транзакции |
-999 | 335544689 | ib_error |
Firebird error Ошибка Firebird |
Зарезервированные слова являются частью языка SQL Firebird. Они не могут быть использованы в качестве идентификаторов (например, имён таблиц или процедур), за исключением случаев когда они заключены в двойные кавычки (при использовании 3 диалекта). Вы должны стараться избегать их использования, если на то нет серьёзных причин.
Ключевые слова также являются частью языка. Они имеют особое значение при использовании в определённом контексте, но не являются зарезервированными для монопольного использования самим сервером Firebird. Вы можете использовать их в качестве идентификаторов без заключения в двойные кавычки.
ADD | EXISTS | POST_EVENT |
ADMIN | EXTERNAL | PRECISION |
ALL | EXTRACT | PRIMARY |
ALTER | FETCH | PROCEDURE |
AND | FILTER | RDB$DB_KEY |
ANY | FLOAT | REAL |
AS | FOR | RECORD_VERSION |
AT | FOREIGN | RECREATE |
AVG | FROM | RECURSIVE |
BEGIN | FULL | REFERENCES |
BETWEEN | FUNCTION | RELEASE |
BIGINT | GDSCODE | RETURNING_VALUES |
BIT_LENGTH | GLOBAL | RETURNS |
BLOB | GRANT | REVOKE |
BOTH | GROUP | RIGHT |
BY | HAVING | ROLLBACK |
CASE | HOUR | ROW_COUNT |
CAST | IN | ROWS |
CHAR | INDEX | SAVEPOINT |
CHAR_LENGTH | INNER | SECOND |
CHARACTER | INSENSITIVE | SELECT |
CHARACTER_LENGTH | INSERT | SENSITIVE |
CHECK | INSERTING | SET |
CLOSE | INT | SIMILAR |
COLLATE | INTEGER | SMALLINT |
COLUMN | INTO | SOME |
COMMIT | IS | SQLCODE |
CONNECT | JOIN | SQLSTATE |
CONSTRAINT | LEADING | START |
COUNT | LEFT | SUM |
CREATE | LIKE | TABLE |
CROSS | LONG | THEN |
CURRENT | LOWER | TIME |
CURRENT_CONNECTION | MAX | TIMESTAMP |
CURRENT_DATE | MAXIMUM_SEGMENT | TO |
CURRENT_ROLE | MERGE | TRAILING |
CURRENT_TIME | MIN | TRIGGER |
CURRENT_TIMESTAMP | MINUTE | TRIM |
CURRENT_TRANSACTION | MONTH | UNION |
CURRENT_USER | NATIONAL | UNIQUE |
CURSOR | NATURAL | UPDATE |
DATE | NCHAR | UPDATING |
DAY | NO | UPPER |
DEC | NOT | USER |
DECIMAL | NULL | USING |
DECLARE | NUMERIC | VALUE |
DEFAULT | OCTET_LENGTH | VALUES |
DELETE | OF | VARCHAR |
DELETING | ON | VARIABLE |
DISCONNECT | ONLY | VARYING |
DISTINCT | OPEN | VIEW |
DOUBLE | OR | WHEN |
DROP | ORDER | WHERE |
ELSE | OUTER | WHILE |
END | PARAMETER | WITH |
ESCAPE | PLAN | YEAR |
EXECUTE | POSITION |
Следующие термины имеют особое значение в DSQL Firebird. Некоторые из них также являются и зарезервированными словами.
!< | DISTINCT | PLACING |
^< | DO | PLAN |
^= | DOMAIN | POSITION |
^> | DOUBLE | POST_EVENT |
, | DROP | POWER |
:= | ELSE | PRECISION |
!= | END | PRESERVE |
!> | ENTRY_POINT | PRIMARY |
( | ESCAPE | PRIVILEGES |
) | EXCEPTION | PROCEDURE |
< | EXECUTE | PROTECTED |
<= | EXISTS | RAND |
<> | EXIT | RDB$DB_KEY |
= | EXP | READ |
> | EXTERNAL | REAL |
>= | EXTRACT | RECORD_VERSION |
|| | FETCH | RECREATE |
~< | FILE | RECURSIVE |
~= | FILTER | REFERENCES |
~> | FIRST | RELEASE |
ABS | FIRSTNAME | REPLACE |
ACCENT | FLOAT | REQUESTS |
ACOS | FLOOR | RESERV |
ACTION | FOR | RESERVING |
ACTIVE | FOREIGN | RESTART |
ADD | FREE_IT | RESTRICT |
ADMIN | FROM | RETAIN |
AFTER | FULL | RETURNING |
ALL | FUNCTION | RETURNING_VALUES |
ALTER | GDSCODE | RETURNS |
ALWAYS | GEN_ID | REVERSE |
AND | GEN_UUID | REVOKE |
ANY | GENERATED | RIGHT |
AS | GENERATOR | ROLE |
ASC | GLOBAL | ROLLBACK |
ASCENDING | GRANT | ROUND |
ASCII_CHAR | GRANTED | ROW_COUNT |
ASCII_VAL | GROUP | ROW_NUMBER |
ASIN | HASH | ROWS |
AT | HAVING | RPAD |
ATAN | HOUR | SAVEPOINT |
ATAN2 | IF | SCALAR_ARRAY |
AUTO | IGNORE | SCHEMA |
AUTONOMOUS | IIF | SECOND |
AVG | IN | SEGMENT |
BACKUP | INACTIVE | SELECT |
BEFORE | INDEX | SENSITIVE |
BEGIN | INNER | SEQUENCE |
BETWEEN | INPUT_TYPE | SET |
BIGINT | INSENSITIVE | SHADOW |
BIN_AND | INSERT | SHARED |
BIN_NOT | INSERTING | SIGN |
BIN_OR | INT | SIMILAR |
BIN_SHL | INTEGER | SIN |
BIN_SHR | INTO | SINGULAR |
BIN_XOR | IS | SINH |
BIT_LENGTH | ISOLATION | SIZE |
BLOB | JOIN | SKIP |
BLOCK | KEY | SMALLINT |
BOTH | LAST | SNAPSHOT |
BREAK | LASTNAME | SOME |
BY | LEADING | SORT |
CALLER | LEAVE | SOURCE |
CASCADE | LEFT | SPACE |
CASE | LENGTH | SQLCODE |
CAST | LEVEL | SQLSTATE |
CEIL | LIKE | SQRT |
CEILING | LIMBO | STABILITY |
CHAR | LIST | START |
CHAR_LENGTH | LN | STARTING |
CHAR_TO_UUID | LOCK | STARTS |
CHARACTER | LOG | STATEMENT |
CHARACTER_LENGTH | LOG10 | STATISTICS |
CHECK | LONG | SUB_TYPE |
CLOSE | LOWER | SUBSTRING |
COALESCE | LPAD | SUM |
COLLATE | MANUAL | SUSPEND |
COLLATION | MATCHED | TABLE |
COLUMN | MATCHING | TAN |
COMMENT | MAX | TANH |
COMMIT | MAXIMUM_SEGMENT | TEMPORARY |
COMMITTED | MAXVALUE | THEN |
COMMON | MERGE | TIME |
COMPUTED | MIDDLENAME | TIMEOUT |
CONDITIONAL | MILLISECOND | TIMESTAMP |
CONNECT | MIN | TO |
CONSTRAINT | MINUTE | TRAILING |
CONTAINING | MINVALUE | TRANSACTION |
COS | MOD | TRIGGER |
COSH | MODULE_NAME | TRIM |
COT | MONTH | TRUNC |
COUNT | NAMES | TWO_PHASE |
CREATE | NATIONAL | TYPE |
CROSS | NATURAL | UNCOMMITTED |
CSTRING | NCHAR | UNDO |
CURRENT | NEXT | UNION |
CURRENT_CONNECTION | NOT | UNIQUE |
CURRENT_DATE | NULL | UPDATE |
CURRENT_ROLE | NULLIF | UPDATING |
CURRENT_TIME | NULLS | UPPER |
CURRENT_TIMESTAMP | NUMERIC | USER |
CURRENT_TRANSACTION | OCTET_LENGTH | USING |
CURRENT_USER | OF | UUID_TO_CHAR |
CURSOR | ON | VALUE |
DATA | ONLY | VALUES |
DATABASE | OPEN | VARCHAR |
DATE | OPTION | VARIABLE |
DATEADD | OR | VARYING |
DATEDIFF | ORDER | VIEW |
DAY | OS_NAME | WAIT |
DEC | OUTER | WEEK |
DECIMAL | OUTPUT_TYPE | WEEKDAY |
DECLARE | OVER | WHEN |
DECODE | OVERFLOW | WHERE |
DEFAULT | OVERLAY | WHILE |
DELETE | PAD | WITH |
DELETING | PAGE | WORK |
DESC | PAGE_SIZE | WRITE |
DESCENDING | PAGES | YEAR |
DESCRIPTOR | PARAMETER | YEARDAY |
DIFFERENCE | PASSWORD | |
DISCONNECT | PI |
При первоначальном создании базы данных система управления базами данных создаёт множество системных таблиц. В системных таблицах хранятся метаданные — описания всех объектов базы данных. Системные таблицы содержат префикс RDB$ в имени.
Таблица D.1. Системные таблицы
Таблица | Содержание |
---|---|
RDB$BACKUP_HISTORY | Хранит историю копирования базы данных с помощью nbackup. |
RDB$CHARACTER_SETS | Описание доступных наборов символов в базе данных. |
RDB$CHECK_CONSTRAINTS | Соответствие имён триггеров именам ограничений, связанных с характеристиками NOT NULL, ограничениями CHECK и предложениями ON UPDATE и ON DELETE в ограничениях внешнего ключа. |
RDB$COLLATIONS | Порядки сортировки для всех наборов символов. |
RDB$DATABASE | Основные данные о базе данных. |
RDB$DEPENDENCIES | Сведения о зависимостях между объектами базы данных. |
RDB$EXCEPTIONS | Пользовательские исключения базы данных. |
RDB$FIELD_DIMENSIONS | Размерности столбцов, являющихся массивами. |
RDB$FIELDS | Характеристики столбцов и доменов, как системных, так и созданных пользователем. |
RDB$FILES | Сведения о вторичных файлах и файлах теневых копий. |
RDB$FILTERS | Данные о BLOB-фильтрах. |
RDB$FORMATS | Данные об изменениях таблиц. |
RDB$FUNCTION_ARGUMENTS | Параметры хранимых или внешних функций. |
RDB$FUNCTIONS | Описание хранимых или внешних функций. |
RDB$GENERATORS | Сведения о генераторах (последовательностях). |
RDB$INDEX_SEGMENTS | Сегменты и позиции индексов. |
RDB$INDICES | Определение индексов базы данных (созданных пользователем или системой). |
RDB$LOG_FILES | В настоящей версии не используется. |
RDB$PAGES | Сведения о страницах базы данных. |
RDB$PROCEDURE_PARAMETERS | Параметры хранимых процедур. |
RDB$PROCEDURES | Описания хранимых процедур. |
RDB$REF_CONSTRAINTS | Описания именованных ограничений базы данных (внешних ключей). |
RDB$RELATION_CONSTRAINTS | Описание всех ограничений на уровне таблиц. |
RDB$RELATION_FIELDS | Характеристики столбцов таблиц. |
RDB$RELATIONS | Заголовки таблиц и представлений. |
RDB$ROLES | Определение ролей. |
RDB$SECURITY_CLASSES | Списки управления доступом. |
RDB$TRANSACTIONS | Состояние транзакций при обращении к нескольким базам данных. |
RDB$TRIGGER_MESSAGES | Сообщения триггеров. |
RDB$TRIGGERS | Описания триггеров. |
RDB$TYPES | Описание перечислимых типов данных. |
RDB$USER_PRIVILEGES | Полномочия пользователей системы. |
RDB$VIEW_RELATIONS | Описывает представления. Содержит имена таблиц используемые при определении представления. |
Таблица хранит историю копирования базы данных при помощи утилиты nbackup.
Таблица D.2. Описание столбцов таблицы RDB$BACKUP_HISTORY
Наименование столбца | Тип данных | Описание |
---|---|---|
RDB$BACKUP_ID | INTEGER | Присваиваемый ядром идентификатор. |
RDB$TIMESTAMP | DATE | Дата и время выполнения копирования. |
RDB$BACKUP_LEVEL | INTEGER | Уровень копирования. |
RDB$GUID | CHAR(38) | Уникальный идентификатор. |
RDB$SCN | INTEGER | Системный номер. |
RDB$FILE_NAME | VARCHAR(255) | Полный путь и имя файла копии. |
Содержит наборы символов, доступные в базе данных.
Таблица D.3. Описание столбцов таблицы RDB$CHARACTER_SETS
Наименование столбца | Тип данных | Описание |
---|---|---|
RDB$CHARACTER_SET_NAME | CHAR(31) | Имя набора символов. |
RDB$FORM_OF_USE | CHAR(31) | Не используется. |
RDB$NUMBER_OF_CHARACTERS | INTEGER | Количество символов в наборе. Для существующих наборов символов не используется. |
RDB$DEFAULT_COLLATE_NAME | CHAR(31) | Имя порядка сортировки по умолчанию для набора символов. |
RDB$CHARACTER_SET_ID | SMALLINT | Уникальный идентификатор набора символов. |
RDB$SYSTEM_FLAG | SMALLINT | Системный флаг: имеет значение 1, если набор символов был определён в системе при создании базы данных; значение 0 для набора символов, определённого пользователем. |
RDB$DESCRIPTION | BLOB TEXT | Произвольное текстовое описание набора символов. |
RDB$FUNCTION_NAME | CHAR(31) | Имя внешней функции для наборов символов, определённых пользователем, доступ к которым осуществляется через внешнюю функцию. |
RDB$BYTES_PER_CHARACTER | SMALLINT | Количество байтов для представления одного символа. |
Описывает соответствие имён триггеров именам ограничений, связанных с характеристиками NOT NULL, ограничениями CHECK и предложениями ON UPDATE, ON DELETE в ограничениях внешнего ключа.
Таблица D.4. Описание столбцов таблицы RDB$CHECK_CONSTRAINTS
Наименование столбца | Тип данных | Описание |
---|---|---|
RDB$CONSTRAINT_NAME | CHAR(31) | Имя ограничения. Задаётся пользователем или автоматически генерируется системой. |
RDB$TRIGGER_NAME | CHAR(31) | Для ограничения CHECK — это имя триггера, который поддерживает данное ограничение. Для ограничения NOT NULL — это имя столбца, к которому применяется ограничение. Для ограничения внешнего ключа – это имя триггера, который поддерживает предложения ON UPDATE, ON DELETE. |
Порядки сортировки для наборов символов.
Таблица D.5. Описание столбцов таблицы RDB$COLLATIONS
Наименование столбца | Тип данных | Описание |
---|---|---|
RDB$COLLATION_NAME | CHAR(31) | Имя порядка сортировки. |
RDB$COLLATION_ID | SMALLINT | Идентификатор порядка сортировки. Вместе с идентификатором набора символов является уникальным идентификатором порядка сортировки. |
RDB$CHARACTER_SET_ID | SMALLINT | Идентификатор набора символов. Вместе с идентификатором порядка сортировки является уникальным идентификатором. |
RDB$COLLATION_ATTRIBUTES | SMALLINT | Атрибуты сортировки. Представляет собой битовую маску, где 1-й бит показывает учитывать ли конечные пробелы при сравнении (0 — NO PAD; 1 — PAD SPACE); 2-й бит показывает является ли сравнение чувствительным к регистру символов (0 — CASE SENSITIVE, 1 — CASE INSENSITIVE); 3-й бит показывает будет ли сравнение чувствительным к акцентам (0 — ACCENT SENSITIVE, 1 — ACCENT SENSITIVE). Таким образом, значение 5 означает, что сравнение не является чувствительным к конечным пробелам и к акцентированным буквам. |
RDB$SYSTEM_FLAG | SMALLINT | Признак: определён пользователем — значение 0; определён в системе — значение 1. |
RDB$DESCRIPTION | BLOB TEXT | Произвольное текстовое описание порядка сортировки. |
RDB$FUNCTION_NAME | CHAR(31) | В настоящий момент не используется. |
RDB$BASE_COLLATION_NAME | CHAR(31) | Имя базового порядка сортировки для данного порядка сортировки. |
RDB$SPECIFIC_ATTRIBUTES | BLOB TEXT | Описание особых атрибутов. |
Основные данные о базе данных. Содержит только одну запись.
Таблица D.6. Описание столбцов таблицы RDB$DATABASE
Наименование столбца | Тип данных | Описание |
---|---|---|
RDB$DESCRIPTION | BLOB TEXT | Текст примечания для базы данных. |
RDB$RELATION_ID | SMALLINT | Количество таблиц и представлений в базе данных. |
RDB$SECURITY_CLASS | CHAR(31) | Класс безопасности, определённый в RDB$SECURITY_CLASSES, для обращения к общим для базы данных ограничениям доступа. |
RDB$CHARACTER_SET_NAME | CHAR(31) | Имя набора символов по умолчанию для базы данных, установленного в предложении DEFAULT CHARACTER SET при создании базы данных. NULL — набор символов NONE. |
Сведения о зависимостях между объектами базы данных.
Таблица D.7. Описание столбцов таблицы RDB$DEPENDENCIES
Наименование столбца | Тип данных | Описание |
---|---|---|
RDB$DEPENDENT_NAME | CHAR(31) | Имя представления, процедуры, триггера, ограничения CHECK или вычисляемого столбца, для которого описывается зависимость. |
RDB$DEPENDED_ON_NAME | CHAR(31) | Объект, зависящий от описываемого объекта — таблица, на которую ссылается представление, процедура, триггер, ограничение CHECK или вычисляемый столбец. |
RDB$FIELD_NAME | CHAR(31) | Имя столбца в зависимой таблице, на который ссылается представление, процедура, триггер, ограничение CHECK или вычисляемый столбец. |
RDB$DEPENDENT_TYPE | SMALLINT |
Идентифицирует тип объекта, для которого описывается зависимость:
|
RDB$DEPENDED_ON_TYPE | SMALLINT |
Идентифицирует тип зависимого объекта:
|
Пользовательские исключения базы данных.
Таблица D.8. Описание столбцов таблицы RDB$EXCEPTIONS
Наименование столбца | Тип данных | Описание |
---|---|---|
RDB$EXCEPTION_NAME | CHAR(31) | Имя пользовательского исключения. |
RDB$EXCEPTION_NUMBER | INTEGER | Назначенный системой уникальный номер исключения. |
RDB$MESSAGE | CHAR(1023) | Текст сообщения в исключении. |
RDB$DESCRIPTION | BLOB TEXT | Произвольное текстовое описание исключения. |
RDB$SYSTEM_FLAG | SMALLINT | Признак: определено пользователем = 0; определено системой = 1 или выше. |
Размерности столбцов, являющихся массивами.
Таблица D.9. Описание столбцов таблицы RDB$FIELD_DIMENSIONS
Наименование столбца | Тип данных | Описание |
---|---|---|
RDB$FIELD_NAME | CHAR(31) | Имя столбца, являющегося массивом. Должно содержаться в поле RDB$FIELD_NAME таблицы RDB$FIELDS. |
RDB$DIMENSION | SMALLINT | Определяет одну размерность столбца массива. Нумерация размерностей начинается с 0. |
RDB$LOWER_BOUND | INTEGER | Нижняя граница этой размерности. |
RDB$UPPER_BOUND | INTEGER | Верхняя граница описываемой размерности. |
Характеристики столбцов и доменов, как системных, так и созданных пользователем. В этой таблице хранятся подробности атрибутов всех столбцов.
Столбец RDB$FIELDS.RDB$FIELD_NAME ссылается на RDB$RELATION_FIELDS.RDB$FIELD_SOURCE, но не на RDB$RELATION_FIELDS.RDB$FIELD_NAME.
Таблица D.10. Описание столбцов таблицы RDB$FIELDS
Наименование столбца | Тип данных | Описание |
---|---|---|
RDB$FIELD_NAME | CHAR(31) | Уникальное имя домена, созданного пользователем, или домена, автоматически построенного ядром Firebird для столбца таблицы. Во втором случае имя будет начинаться с символов 'RDB$'. |
RDB$QUERY_NAME | CHAR(31) | Не используется. |
RDB$VALIDATION_BLR | BLOB BLR | Двоичное представление (BLR) выражения SQL, задающее проверку значения CHECK у домена. |
RDB$VALIDATION_SOURCE | BLOB TEXT | Оригинальный исходный текст на языке SQL, задающий проверку значения CHECK. |
RDB$COMPUTED_BLR | BLOB BLR | Двоичное представление (BLR) выражения SQL, которое используется сервером базы данных для вычисления при обращении к столбцу COMPUTED BY. |
RDB$COMPUTED_SOURCE | BLOB TEXT | Оригинальный исходный текст выражения, которое определяет столбец COMPUTED BY. |
RDB$DEFAULT_VALUE | BLOB BLR | Значение по умолчанию в двоичном виде BLR. |
RDB$DEFAULT_SOURCE | BLOB TEXT | Значение по умолчанию в исходном виде на языке SQL. |
RDB$FIELD_LENGTH | SMALLINT | Размер столбца в байтах. FLOAT, DATE, TIME, INTEGER занимают 4 байта. DOUBLE PRECISION, BIGINT, TIMESTAMP и идентификатор BLOB — 8 байтов. Для типов данных CHAR и VARCHAR столбец задаёт максимальное количество байтов, указанное при объявлении строкового домена (столбца). |
RDB$FIELD_SCALE | SMALLINT | Отрицательное число задаёт масштаб для столбцов DECIMAL и NUMERIC — количество дробных знаков после десятичной точки. |
RDB$FIELD_TYPE | SMALLINT |
Код типа данных для столбца:
Коды для DECIMAL и NUMERIC имеют тот же размер, что и целые типы, используемые для их хранения. |
RDB$FIELD_SUB_TYPE | SMALLINT |
Для типа данных BLOB задаёт подтип:
Для типа данных CHAR задаёт:
Для целочисленных типов данных (SMALLINT, INTEGER, BIGINT) и чисел с фиксированной точкой (NUMERIC, DECIMAL) задаёт конкретный тип данных:
|
RDB$MISSING_VALUE | BLOB BLR | Не используется. |
RDB$MISSING_SOURCE | BLOB TEXT | Не используется. |
RDB$DESCRIPTION | BLOB TEXT | Произвольный текст комментария для домена (столбца таблицы). |
RDB$SYSTEM_FLAG | SMALLINT | Признак: значение 1 – домен, автоматически созданный системой, значение 0 – домен определён пользователем. |
RDB$QUERY_HEADER | BLOB TEXT | Не используется. |
RDB$SEGMENT_LENGTH | SMALLINT | Для столбцов BLOB задаёт длину буфера BLOB в байтах. Для остальных типов данных содержит NULL. |
RDB$EDIT_STRING | VARCHAR(127) | Не используется. |
RDB$EXTERNAL_LENGTH | SMALLINT | Длина столбца в байтах, если он входит в состав внешней таблицы. Всегда NULL для обычных таблиц. |
RDB$EXTERNAL_SCALE | SMALLINT | Показатель степени для столбца целого типа данных во внешней таблице; задаётся степенью 10, на которую умножается целое. |
RDB$EXTERNAL_TYPE | SMALLINT |
Тип данных поля, как он представляется во внешней таблице.
Коды для DECIMAL и NUMERIC имеют тот же размер, что и целые типы, используемые для их хранения. |
RDB$DIMENSIONS | SMALLINT | Задаёт количество размерностей массива, если столбец был определён как массив. Для столбцов, не являющихся массивами, всегда NULL. |
RDB$NULL_FLAG | SMALLINT | Указывает, может ли столбец принимать пустое значение (в поле будет значение NULL) или не может (в поле будет содержаться значение 1). |
RDB$CHARACTER_LENGTH | SMALLINT | Длина столбцов CHAR или VARCHAR в символах (не в байтах). |
RDB$COLLATION_ID | SMALLINT | Идентификатор порядка сортировки для символьного столбца или домена. Если не задан, значением поля будет 0. |
RDB$CHARACTER_SET_ID | SMALLINT | Идентификатора набора символов для символьного столбца, столбца BLOB или домена. |
RDB$FIELD_PRECISION | SMALLINT | Указывает общее количество цифр для числового типа данных с фиксированной точкой (DECIMAL и NUMERIC). Для целочисленных типов данных значением является 0, для всех остальных типов данных – NULL. |
RDB$SECURITY_CLASS | CHAR(31) | Может ссылаться на класс безопасности, определённый в таблице RDB$SECURITY_CLASSES для применения ограничений управления доступом для всех пользователей этого домена. |
RDB$OWNER_NAME | CHAR(31) | Имя пользователя – владельца (создателя) домена. |
Сведения о вторичных файлах и файлах оперативных копий.
Таблица D.11. Описание столбцов таблицы RDB$FILES
Наименование столбца | Тип данных | Описание |
---|---|---|
RDB$FILE_NAME | VARCHAR(255) | Полный путь к файлу и имя вторичного файла базы данных в многофайловой базе данных или файла оперативной копии. |
RDB$FILE_SEQUENCE | SMALLINT | Порядковый номер вторичного файла в последовательности или номер файла копии в наборе оперативных копий. |
RDB$FILE_START | INTEGER | Начальный номер страницы вторичного файла или файла оперативной копии. |
RDB$FILE_LENGTH | INTEGER | Длина файла в страницах базы данных. |
RDB$FILE_FLAGS | SMALLINT | Для внутреннего использования. |
RDB$SHADOW_NUMBER | SMALLINT | Номер набора оперативных копий. Если строка описывает вторичный файл базы данных, то значением поля будет NULL или 0. |
Содержит данные о BLOB-фильтрах.
Таблица D.12. Описание столбцов таблицы RDB$FILTERS
Наименование столбца | Тип данных | Описание |
---|---|---|
RDB$FUNCTION_NAME | CHAR(31) | Уникальное имя фильтра BLOB. |
RDB$DESCRIPTION | BLOB TEXT | Написанная пользователем документация о фильтре BLOB и используемых двух подтипах. |
RDB$MODULE_NAME | VARCHAR(255) | Имя динамической библиотеки / совместно используемого объекта, где расположен код фильтра BLOB. |
RDB$ENTRYPOINT | CHAR(255) | Точка входа в библиотеке фильтров для этого фильтра BLOB. |
RDB$INPUT_SUB_TYPE | SMALLINT | Подтип BLOB для преобразуемых данных. |
RDB$OUTPUT_SUB_TYPE | SMALLINT | Подтип BLOB, в который преобразуются входные данные. |
RDB$SYSTEM_FLAG | SMALLINT | Признак: внешне определённый фильтр (т.е. определённый пользователем = значение 0, внутренне определённый = значение 1 или более) |
Данные об изменениях таблиц. Каждый раз, когда таблица изменяется, таблица получает новый номер формата. Когда номер формата любой таблицы достигает 255, вся база данных становится недоступной для работы с ней. Тогда нужно выполнить резервное копирование, восстановить эту копию и продолжить работу с заново созданной базой данных.
Таблица D.13. Описание столбцов таблицы RDB$FORMATS
Наименование столбца | Тип данных | Описание |
---|---|---|
RDB$RELATION_ID | SMALLINT | Идентификатор таблицы или представления. |
RDB$FORMAT | SMALLINT | Идентификатор формата таблицы. Форматов может быть до 255. |
RDB$DESCRIPTOR | BLOB FORMAT | Отображение в виде BLOB столбцов и характеристик данных на момент, когда была создана запись формата. |
Параметры хранимых или внешних функций.
Таблица D.14. Описание столбцов таблицы RDB$FUNCTION_ARGUMENTS
Наименование столбца | Тип данных | Описание |
---|---|---|
RDB$FUNCTION_NAME | CHAR(31) | Имя функции. |
RDB$ARGUMENT_POSITION | SMALLINT | Позиция аргумента в списке аргументов. |
RDB$MECHANISM | SMALLINT |
Механизм передачи параметра для Legacy функций:
|
RDB$FIELD_TYPE | SMALLINT |
Код типа данных аргумента:
|
RDB$FIELD_SCALE | SMALLINT | Масштаб для целого числа или аргумента с фиксированной точкой. Это показатель числа 10. |
RDB$FIELD_LENGTH | SMALLINT |
Длина аргумента в байтах:
|
RDB$FIELD_SUB_TYPE | SMALLINT | Для аргумента типа данных BLOB задаёт подтип BLOB. |
RDB$CHARACTER_SET_ID | SMALLINT | Идентификатор набора символов для символьного аргумента. |
RDB$FIELD_PRECISION | SMALLINT | Количество цифр точности, допустимой для типа данных аргумента. |
RDB$CHARACTER_LENGTH | SMALLINT | Длина аргумента CHAR или VARCHAR в символах (но не в байтах). |
Описание хранимых или внешних функций.
Таблица D.15. Описание столбцов таблицы RDB$FUNCTIONS
Наименование столбца | Тип данных | Описание |
---|---|---|
RDB$FUNCTION_NAME | CHAR(31) | Имя функции. |
RDB$FUNCTION_TYPE | SMALLINT | В настоящий момент не используется. |
RDB$QUERY_NAME | CHAR(31) | В настоящий момент не используется. |
RDB$DESCRIPTION | BLOB TEXT | Произвольный текст комментария к функции. |
RDB$MODULE_NAME | VARCHAR(255) | Имя внешнего модуля (динамической библиотеки), где расположен код функции. |
RDB$ENTRYPOINT | CHAR(255) | Имя точки входа в библиотеке, где находится эта функция. |
RDB$RETURN_ARGUMENT | SMALLINT | Номер позиции возвращаемого аргумента в списке параметров, соответствующем входным аргументам. |
RDB$SYSTEM_FLAG | SMALLINT |
Признак определения функции: 0 — определённая системой, 1 — определённая пользователем. |
Сведения о генераторах (последовательностях).
Таблица D.16. Описание столбцов таблицы RDB$GENERATORS
Наименование столбца | Тип данных | Описание |
---|---|---|
RDB$GENERATOR_NAME | CHAR(31) | Уникальное имя генератора. |
RDB$GENERATOR_ID | SMALLINT | Назначаемый системой уникальный идентификатор для генератора. |
RDB$SYSTEM_FLAG | SMALLINT | Признак: значение 0 — генератор определён пользователем, значение 1 или выше — определён системой. |
RDB$DESCRIPTION | BLOB TEXT | Произвольный текст примечания к генератору. |
Сегменты и позиции индексов. Таблица описывает все столбцы таблицы, входящие в состав конкретного индекса. Для каждого столбца индекса создаётся отдельная строка в данной таблице.
Таблица D.17. Описание столбцов таблицы RDB$INDEX_SEGMENTS
Наименование столбца | Тип данных | Описание |
---|---|---|
RDB$INDEX_NAME | CHAR(31) | Имя индекса, к которому относится данный сегмент. Должно соответствовать главной записи в системной таблице RDB$INDICES. |
RDB$FIELD_NAME | CHAR(31) | Имя одного из столбцов, входящего в состав индекса. Должно соответствовать значению в столбце RDB$FIELD_NAME в таблице RDB$RELATION_FIELDS. |
RDB$FIELD_POSITION | SMALLINT | Позиция столбца в индексе. Нумерация начинается с нуля. |
RDB$STATISTICS | DOUBLE PRECISION | Последнее известное (рассчитанное) значение селективности индекса по данному столбцу. |
Определение индексов базы данных (созданных пользователем или системой). Описывает каждый индекс, созданный пользователем или системой. Для каждого столбца таблицы, входящего в состав индекса, присутствует строка системной таблицы RDB$INDEX_SEGMENTS, где описываются характеристики столбца индекса.
Таблица D.18. Описание столбцов таблицы RDB$INDICES
Наименование столбца | Тип данных | Описание |
---|---|---|
RDB$INDEX_NAME | CHAR(31) | Уникальное имя индекса, заданное пользователем или автоматически сгенерированное системой. |
RDB$RELATION_NAME | CHAR(31) | Имя таблицы, к которой применяется индекс. Соответствует RDB$RELATION_NAME в строке таблицы RDB$RELATIONS. |
RDB$INDEX_ID | SMALLINT | Внутренний (системный) идентификатор индекса. |
RDB$UNIQUE_FLAG | SMALLINT |
Указывает, является ли индекс уникальным:
|
RDB$DESCRIPTION | BLOB TEXT | Произвольный текст комментария к индексу. |
RDB$SEGMENT_COUNT | SMALLINT | Количество сегментов (столбцов) в индексе. |
RDB$INDEX_INACTIVE | SMALLINT |
Указывает, является ли в настоящий момент индекс активным:
|
RDB$INDEX_TYPE | SMALLINT |
Направление индекса:
|
RDB$FOREIGN_KEY | CHAR(31) | Имя ассоциированного ограничения внешнего ключа, если существует. |
RDB$SYSTEM_FLAG | SMALLINT | Указывает, является ли индекс определённым системой (значение 1 или выше) или пользователем (значение 0). |
RDB$EXPRESSION_BLR | BLOB BLR | Выражение, записанное на языке двоичного представления (BLR). Будет использовано для вычисления во время выполнения, когда будут реализованы индексы выражений. |
RDB$EXPRESSION_SOURCE | BLOB TEXT | Исходный текст выражения. Будет использовано, когда будут реализованы индексы выражений. |
RDB$STATISTICS | DOUBLE PRECISION | Хранит самую последнюю селективность индекса, вычисленную при помощи оператора SET STATISTICS. |
В настоящей версии не используется.
Таблица D.19. Описание столбцов таблицы RDB$LOG_FILES
Наименование столбца | Тип данных | Описание |
---|---|---|
RDB$FILE_NAME | VARCHAR(255) | Не используется. |
RDB$FILE_SEQUENCE | SMALLINT | Не используется. |
RDB$FILE_LENGTH | INTEGER | Не используется. |
RDB$FILE_PARTITIONS | SMALLINT | Не используется. |
RDB$FILE_P_OFFSET | INTEGER | Не используется. |
RDB$FILE_FLAGS | SMALLINT | Не используется. |
Сведения о страницах базы данных.
Таблица D.20. Описание столбцов таблицы RDB$PAGES
Наименование столбца | Тип данных | Описание |
---|---|---|
RDB$PAGE_NUMBER | INTEGER | Уникальный номер физически созданной страницы базы данных. |
RDB$RELATION_ID | SMALLINT | Идентификатор таблицы, для которой выделена эта страница. |
RDB$PAGE_SEQUENCE | INTEGER | Последовательный номер страницы по отношению к другим страницам, выделенным для данной таблицы. |
RDB$PAGE_TYPE | SMALLINT | Описывает тип страницы. Для системного использования. |
Описывает параметры хранимых процедур.
Таблица D.21. Описание столбцов таблицы RDB$PROCEDURE_PARAMETERS
Наименование столбца | Тип данных | Описание |
---|---|---|
RDB$PARAMETER_NAME | CHAR(31) | Имя параметра. |
RDB$PROCEDURE_NAME | CHAR(31) | Имя процедуры, в которой используется параметр. |
RDB$PARAMETER_NUMBER | SMALLINT | Последовательный номер параметра. |
RDB$PARAMETER_TYPE | SMALLINT | Указывает, является ли параметр входным (значение 0) или выходным (значение 1). |
RDB$FIELD_SOURCE | CHAR(31) | Имя домена, созданного пользователем (при использовании ссылки на домен вместо типа), или домена, автоматически построенного системой для параметра процедуры. Во втором случае имя будет начинаться с символов 'RDB$'. |
RDB$DESCRIPTION | BLOB TEXT | Текст произвольного примечания к параметру. |
RDB$SYSTEM_FLAG | SMALLINT | Указывает, является ли параметр определённым системой (значение 1 и выше) или пользователем (значение 0). |
RDB$DEFAULT_VALUE | BLOB BLR | Значение по умолчанию на языке BLR. |
RDB$DEFAULT_SOURCE | BLOB TEXT | Значение по умолчанию в исходном виде на языке SQL. |
RDB$COLLATION_ID | SMALLINT | Идентификатор используемого порядка сортировки для символьного параметра. |
RDB$NULL_FLAG | SMALLINT | Признак допустимости пустого значения NULL. |
RDB$PARAMETER_MECHANISM | SMALLINT |
Механизм передачи параметра:
|
RDB$FIELD_NAME | CHAR(31) | Имя столбца, на которое ссылается параметр с помощью предложения TYPE OF COLUMN. |
RDB$RELATION_NAME | CHAR(31) | Имя таблицы, на которую ссылается параметр с помощью предложения TYPE OF COLUMN. |
Описывает хранимые процедуры.
Таблица D.22. Описание столбцов таблицы RDB$PROCEDURES
Наименование столбца | Тип данных | Описание |
---|---|---|
RDB$PROCEDURE_NAME | CHAR(31) | Имя хранимой процедуры. |
RDB$PROCEDURE_ID | SMALLINT | Уникальный идентификатор процедуры. |
RDB$PROCEDURE_INPUTS | SMALLINT | Указывает количество входных параметров или их отсутствие (значение NULL). |
RDB$PROCEDURE_OUTPUTS | SMALLINT | Указывает количество выходных параметров или их отсутствие (значение NULL). |
RDB$DESCRIPTION | BLOB TEXT | Произвольный текст примечания к процедуре. |
RDB$PROCEDURE_SOURCE | BLOB TEXT | Исходный код процедуры на языке SQL. |
RDB$PROCEDURE_BLR | BLOB BLR | Двоичное представление (BLR) кода процедуры. |
RDB$SECURITY_CLASS | CHAR(31) | Может указывать на класс безопасности, определённый в системной таблице RDB$SECURITY_CLASSES, для применения ограничений управления доступом. |
RDB$OWNER_NAME | CHAR(31) | Имя пользователя - владельца (создателя) процедуры. |
RDB$RUNTIME | BLOB | Описание метаданных процедуры. Внутреннее использование для оптимизации. |
RDB$SYSTEM_FLAG | SMALLINT | Указывает, что процедура определена пользователем (значение 0) или системой (значение 1 или выше). |
RDB$PROCEDURE_TYPE | SMALLINT |
Тип процедуры:
|
RDB$VALID_BLR | SMALLINT | Указывает, остаётся ли текст хранимой процедуры корректным после последнего изменения процедуры при помощи оператора ALTER PROCEDURE. |
RDB$DEBUG_INFO | BLOB | Содержит отладочную информацию о переменных, используемых в хранимой процедуре. |
Описания именованных ограничений базы данных (внешних ключей).
Таблица D.23. Описание столбцов таблицы RDB$REF_CONSTRAINTS
Наименование столбца | Тип данных | Описание |
---|---|---|
RDB$CONSTRAINT_NAME | CHAR(31) | Имя ограничения внешнего ключа. Задаётся пользователем или автоматически генерируется системой. |
RDB$CONST_NAME_UQ | CHAR(31) | Имя ограничения первичного или уникального ключа, на которое ссылается предложение REFERENCES в данном ограничении. |
RDB$MATCH_OPTION | CHAR(7) | Не используется. Текущим значением является FULL во всех случаях. |
RDB$UPDATE_RULE | CHAR(11) | Действия по ссылочной целостности, применимые к данному внешнему ключу, когда изменяется первичный (уникальный) ключ родительской таблицы: RESTRICT, NO ACTION, CASCADE, SET NULL, SET DEFAULT. |
RDB$DELETE_RULE | CHAR(11) | Действия по ссылочной целостности, применимые к данному внешнему ключу, когда удаляется первичный (уникальный) ключ родительской таблицы: RESTRICT, NO ACTION, CASCADE, SET NULL, SET DEFAULT. |
Описание всех ограничений на уровне таблиц: первичного, уникального, внешнего ключей, ограничений CHECK, NOT NULL.
Таблица D.24. Описание столбцов таблицы RDB$RELATION_CONSTRAINTS
Наименование столбца | Тип данных | Описание |
---|---|---|
RDB$CONSTRAINT_NAME | CHAR(31) | Имя ограничения на уровне таблицы, заданное пользователем или автоматически присвоенное системой. |
RDB$CONSTRAINT_TYPE | CHAR(11) | Содержит название типа ограничения: PRIMARY KEY, UNIQUE, FOREIGN KEY, CHECK, NOT NULL. |
RDB$RELATION_NAME | CHAR(31) | Имя таблицы, к которой применяется это ограничение. |
RDB$DEFERRABLE | CHAR(3) | В настоящий момент во всех случаях NO. |
RDB$INITIALLY_DEFERRED | CHAR(3) | В настоящий момент во всех случаях NO. |
RDB$INDEX_NAME | CHAR(31) | Имя индекса, который поддерживает это ограничение (содержит NULL, если ограничением является CHECK или NOT NULL). |
Характеристики столбцов таблиц и представлений.
Таблица D.25. Описание столбцов таблицы RDB$RELATION_FIELDS
Наименование столбца | Тип данных | Описание |
---|---|---|
RDB$FIELD_NAME | CHAR(31) | Имя столбца. |
RDB$RELATION_NAME | CHAR(31) | Имя таблицы (представления), где присутствует описываемый столбец. |
RDB$FIELD_SOURCE | CHAR(31) | Содержит имя домена (определённого пользователем или созданного автоматически системой), на котором основывается данный столбец. |
RDB$QUERY_NAME | CHAR(31) | В настоящей версии системы не используется. |
RDB$BASE_FIELD | CHAR(31) | Только для представления. Имя столбца из базовой таблицы |
RDB$EDIT_STRING | VARCHAR(127) | Не используется. |
RDB$FIELD_POSITION | SMALLINT | Позиция столбца в таблице или представлении. Нумерация начинается с 0. |
RDB$QUERY_HEADER | BLOB TEXT | Не используется. |
RDB$UPDATE_FLAG | SMALLINT | Указывает, является ли столбец обычным столбцом (значение 1) или вычисляемым (значение 0). |
RDB$FIELD_ID | SMALLINT | В настоящей версии системы в точности соответствует значению в столбце RDB$FIELD_POSITION. |
RDB$VIEW_CONTEXT | SMALLINT | Для столбца представления это внутренний идентификатор базовой таблицы, откуда приходит это поле. |
RDB$DESCRIPTION | BLOB TEXT | Примечание к столбцу таблицы или представления. |
RDB$DEFAULT_VALUE | BLOB BLR | Записанное в двоичном виде (BLR) значение по умолчанию — предложение DEFAULT, если оно присутствует при описании столбца таблицы (представления). |
RDB$SYSTEM_FLAG | SMALLINT | Указывает, определено пользователем (значение 0) или системой (значение 1 или выше). |
RDB$SECURITY_CLASS | CHAR(31) | Может ссылаться на класс безопасности, определённый в RDB$SECURITY_CLASSES для применения ограничений управления доступом для всех пользователей этого столбца. |
RDB$COMPLEX_NAME | CHAR(31) | Не используется. |
RDB$NULL_FLAG | SMALLINT | Указывает, допускает ли столбец значения NULL (значение NULL) или не допускает (значение 1). |
RDB$DEFAULT_SOURCE | BLOB TEXT | Исходный текст предложения DEFAULT, если присутствует. |
RDB$COLLATION_ID | SMALLINT | Идентификатор последовательности сортировки в составе набора символов для столбца не по умолчанию. |
Хранит некоторые характеристики таблиц и представлений.
Таблица D.26. Описание столбцов таблицы RDB$RELATIONS
Наименование столбца | Тип данных | Описание |
---|---|---|
RDB$VIEW_BLR | BLOB BLR | Для представления содержит на языке BLR спецификации запроса. Для таблицы в поле содержится NULL. |
RDB$VIEW_SOURCE | BLOB TEXT | Для представления содержит оригинальный исходный текст запроса на языке SQL (включая пользовательские комментарии). Для таблицы в поле содержится NULL. |
RDB$DESCRIPTION | BLOB TEXT | Произвольный текст примечания к таблице (представлению). |
RDB$RELATION_ID | SMALLINT | Внутренний идентификатор таблицы (представления). |
RDB$SYSTEM_FLAG | SMALLINT | Указывает, создана ли таблица (представление) пользователем (значение 0) или системой (значение 1 или выше). |
RDB$DBKEY_LENGTH | SMALLINT | Общая длина ключа. Для таблицы это 8 байтов. Для представления это 8, умноженное на количество таблиц, на которые ссылается представление. |
RDB$FORMAT | SMALLINT | Внутреннее использование. |
RDB$FIELD_ID | SMALLINT | Количество столбцов в таблице (представлении). |
RDB$RELATION_NAME | CHAR(31) | Имя таблицы или представления. |
RDB$SECURITY_CLASS | CHAR(31) | Может ссылаться на класс безопасности, определённый в таблице RDB$SECURITY_CLASSES для применения ограничений управления доступом для всех пользователей этой таблицы (представления). |
RDB$EXTERNAL_FILE | VARCHAR(255) | Полный путь к внешнему файлу данных, если таблица описана с предложением EXTERNAL FILE. |
RDB$RUNTIME | BLOB | Описание метаданных таблицы. Внутреннее использование для оптимизации. |
RDB$EXTERNAL_DESCRIPTION | BLOB | Произвольное примечание к внешнему файлу таблицы. |
RDB$OWNER_NAME | CHAR(31) | Имя пользователя — владельца (создателя) таблицы или представления. |
RDB$DEFAULT_CLASS | CHAR(31) | Класс безопасности по умолчанию. Применяется, когда новый столбец добавляется в таблицу. |
RDB$FLAGS | SMALLINT | Внутренние флаги. |
RDB$RELATION_TYPE | SMALLINT |
Тип описываемого объекта:
|
Определение ролей.
Таблица D.27. Описание столбцов таблицы RDB$ROLES
Наименование столбца | Тип данных | Описание |
---|---|---|
RDB$ROLE_NAME | CHAR(31) | Имя роли. |
RDB$OWNER_NAME | CHAR(31) | Имя пользователя-владельца роли. |
RDB$DESCRIPTION | BLOB TEXT | Произвольный текст примечания к роли. |
RDB$SYSTEM_FLAG | SMALLINT | Системный флаг. |
RDB$SECURITY_CLASS | CHAR(31) | Может ссылаться на класс безопасности, определённый в таблице RDB$SECURITY_CLASSES для применения ограничений управления доступом для всех пользователей этой роли. |
Списки управления доступом.
Таблица D.28. Описание столбцов таблицы RDB$SECURITY_CLASSES
Наименование столбца | Тип данных | Описание |
---|---|---|
RDB$SECURITY_CLASS | CHAR(31) | Имя класса безопасности. |
RDB$ACL | BLOB ACL | Список управления доступом, связанный с классом безопасности. Перечисляет пользователей и их полномочия. |
RDB$DESCRIPTION | BLOB TEXT | Произвольный текст примечания к классу безопасности. |
RDB$TRANSACTIONS хранит состояние распределённых и других транзакций, которые подготовлены для двухфазного подтверждения с явно подготовленным сообщением.
Таблица D.29. Описание столбцов таблицы RDB$TRANSACTIONS
Наименование столбца | Тип данных | Описание |
---|---|---|
RDB$TRANSACTION_ID | INTEGER | Уникальный идентификатор отслеживаемой транзакции. |
RDB$TRANSACTION_STATE | SMALLINT |
Состояние транзакции:
|
RDB$TIMESTAMP | TIMESTAMP | Не используется. |
RDB$TRANSACTION_DESCRIPTION | BLOB | Описывает подготовленную транзакцию и может быть поступающее
пользовательское сообщение
isc_prepare_transaction2 даже если это не
распределённая транзакция. Может быть использовано в случае потери
соединения, которое не может быть восстановлено.
|
Сообщения триггеров.
Таблица D.30. Описание столбцов таблицы RDB$TRIGGER_MESSAGES
Наименование столбца | Тип данных | Описание |
---|---|---|
RDB$TRIGGER_NAME | CHAR(31) | Имя триггера, с которым связано данное сообщение. |
RDB$MESSAGE_NUMBER | SMALLINT | Номер сообщения в пределах одного триггера (от 1 до 32767). |
RDB$MESSAGE | VARCHAR(1023) | Текст сообщения триггера. |
Описания триггеров.
Таблица D.31. Описание столбцов таблицы RDB$TRIGGERS
Наименование столбца | Тип данных | Описание |
---|---|---|
RDB$TRIGGER_NAME | CHAR(31) | Имя триггера. |
RDB$RELATION_NAME | CHAR(31) | Имя таблицы или представления, для которого используется триггер. Если триггер применяется не к событию таблицы, а к событию базы данных, то в этом поле находится NULL. |
RDB$TRIGGER_SEQUENCE | SMALLINT | Последовательность (позиция) триггера. Ноль обычно означает, что последовательность не задана. |
RDB$TRIGGER_TYPE | BIGINT |
Событие, на которое вызывается триггер:
|
RDB$TRIGGER_SOURCE | BLOB TEXT | Хранит исходный код триггера в PSQL. |
RDB$TRIGGER_BLR | BLOB BLR | Хранит триггер в двоичном коде BLR. |
RDB$DESCRIPTION | BLOB TEXT | Текст примечания триггера. |
RDB$TRIGGER_INACTIVE | SMALLINT | Указывает, является ли триггер в настоящее время неактивным (1) или активным (0). |
RDB$SYSTEM_FLAG | SMALLINT | Признак — триггер определён пользователем (0) или системой (1 или выше). |
RDB$FLAGS | SMALLINT | Внутреннее использование. |
RDB$VALID_BLR | SMALLINT | Указывает, остаётся ли текст триггера корректным после последнего изменения триггера при помощи оператора ALTER TRIGGER. |
RDB$DEBUG_INFO | BLOB | Содержит отладочную информацию о переменных, используемых в триггере. |
Описание перечислимых типов данных.
Таблица D.32. Описание столбцов таблицы RDB$TYPES
Наименование столбца | Тип данных | Описание |
---|---|---|
RDB$FIELD_NAME | CHAR(31) | Имя перечисляемого типа. Совпадает с именем столбца, для которого определён данный перечислимый тип. |
RDB$TYPE | SMALLINT |
Задаёт идентификатор для типа. Последовательность чисел является уникальной для каждого отдельного перечислимого типа:
|
RDB$TYPE_NAME | CHAR(31) | Текстовое представление для перечислимого типа. |
RDB$DESCRIPTION | BLOB TEXT | Произвольный текст примечания к перечислимому типу. |
RDB$SYSTEM_FLAG | SMALLINT | Признак: определён пользователем (значение 0) или системой (значение 1 или выше). |
Полномочия пользователей системы.
Таблица D.33. Описание столбцов таблицы RDB$USER_PRIVILEGES
Наименование столбца | Тип данных | Описание |
---|---|---|
RDB$USER | CHAR(31) | Пользователь, роль или объект которому предоставляется данное полномочие. |
RDB$GRANTOR | CHAR(31) | Имя пользователя, предоставляющего полномочие. |
RDB$PRIVILEGE | CHAR(6) |
Привилегия, предоставляемая в полномочии:
|
RDB$GRANT_OPTION | SMALLINT |
Содержит ли полномочие авторизацию WITH GRANT OPTION:
|
RDB$RELATION_NAME | CHAR(31) | Имя объекта (таблица, роль, процедура) на который предоставляется полномочие. |
RDB$FIELD_NAME | CHAR(31) | Имя столбца, к которому применяется привилегия на уровне столбца (только привилегии UPDATE и REFERENCES). |
RDB$USER_TYPE | SMALLINT |
Идентифицирует тип пользователя (или объекта), которому предоставляется привилегия:
|
RDB$OBJECT_TYPE | SMALLINT |
Идентифицирует тип объекта, к которому предоставляется привилегия:
|
Описывает представления.
Таблица D.34. Описание столбцов таблицы RDB$VIEW_RELATIONS
Наименование столбца | Тип данных | Описание |
---|---|---|
RDB$VIEW_NAME | CHAR(31) | Имя представления. |
RDB$RELATION_NAME | CHAR(31) | Имя таблицы, представления или хранимой процедуры на которое ссылается данное представление. |
RDB$VIEW_CONTEXT | SMALLINT | Псевдоним (контекст), используемый для ссылки на столбец представления. Имеет то же значение, что и псевдоним, используемый в самом тексте представления на языке BLR в операторе запроса этого представления. |
RDB$CONTEXT_NAME | CHAR(255) | Текстовый вариант псевдонима, указанного в столбце RDB$VIEW_CONTEXT. |
СУБД Firebird предоставляет возможность отслеживать работу с конкретной базой данных, выполняемую на стороне сервера. Для этих целей используются таблицы мониторинга (имеют префикс имени MON$). Эти таблицы являются виртуальными в том смысле, что до обращения к ним со стороны пользователя, никаких данных в них не записано. Они заполняются данными только в момент запроса пользователя (в том числе, поэтому на такие таблицы бесполезно пытаться создавать триггеры). При этом описания этих таблиц в базе данных присутствуют постоянно.
Ключевым понятием функции мониторинга является снимок активности. Снимок представляет собой текущее состояние базы данных, содержащее множество информации о самой базе данных, активных соединениях, пользователях, транзакциях, подготовленных и выполняемых запросах и т.д.
Снимок создаётся при первой выборке из любой таблицы мониторинга и сохраняется до конца текущей транзакции, чтобы запросы к множеству таблиц (например, главная-подчинённая) всегда возвращал непротиворечивые данные.
Другими словами таблицы мониторинга ведут себя подобно SNAPSHOT TABLE STABILITY
(isc_tpb_consistency
) транзакции, даже если запросы к ним выполняются в транзакции с
меньшим уровнем изолированности.
Для обновления снимка, текущая транзакция должна быть завершена и таблицы мониторинга должны быть запрошены в новом контексте транзакции.
Безопасность:
Полный доступ ко всей информации, предоставляемой таблицами мониторинга, имеют SYSDBA и владелец базы данных;
Обычные пользователи ограничены информацией о собственных соединениях, другие соединения невидимы для них.
Частый сбор информации с помощью таблиц мониторинга в сильно нагруженной среде может негативно отразится на производительности системы.
Таблица E.1. Таблицы мониторинга
Таблица | Содержание |
---|---|
MON$ATTACHMENTS | Сведения о текущих соединениях с базой данных. |
MON$CALL_STACK | Обращения к стеку активными запросами хранимых процедур и триггеров. |
MON$CONTEXT_VARIABLES | Сведения о пользовательских контекстных переменных. |
MON$DATABASE | Сведения о базе данных, с которой выполнено соединение. |
MON$IO_STATS | Статистика по вводу-выводу. |
MON$MEMORY_USAGE | Статистика использования памяти. |
MON$RECORD_STATS | Статистика на уровне записей. |
MON$STATEMENTS | Подготовленные к выполнению операторы. |
MON$TRANSACTIONS | Запущенные на выполнение транзакции. |
Сведения о текущих соединениях с базой данных.
Таблица E.2. Описание столбцов таблицы MON$ATTACHMENTS
Наименование столбца | Тип данных | Описание |
---|---|---|
MON$ATTACHMENT_ID | INTEGER | Идентификатор соединения. |
MON$SERVER_PID | INTEGER | Идентификатор серверного процесса. |
MON$STATE | SMALLINT |
Состояние соединения:
|
MON$ATTACHMENT_NAME | VARCHAR(255) | Строка соединения — полный путь к файлу и имя первичного файла базы данных. |
MON$USER | CHAR(31) | Имя пользователя, соединённого с базой данных. |
MON$ROLE | CHAR(31) | Имя роли, указанное при соединении. Если роль во время соединения не была задана, поле содержит текст NONE. |
MON$REMOTE_PROTOCOL | VARCHAR(10) | Имя удалённого протокола. |
MON$REMOTE_ADDRESS | VARCHAR(255) | Удалённый адрес (адрес и имя сервера). |
MON$REMOTE_PID | INTEGER | Идентификатор удалённого клиентского процесса. |
MON$CHARACTER_SET_ID | SMALLINT | Идентификатор набора символов в соединении. |
MON$TIMESTAMP | TIMESTAMP | Дата и время начала соединения. |
MON$GARBAGE_COLLECTION | SMALLINT | Флаг сборки мусора. |
MON$REMOTE_PROCESS | VARCHAR(255) | Полный путь к файлу и имя программного файла, выполнившего данное соединение. |
MON$STAT_ID | INTEGER | Идентификатор статистики. |
Таблицы мониторинга доступны только для чтения. Однако в сервер встроен механизм для удаления (и только удаления) записей в таблице MON$ATTACHMENTS, что позволяет, закрыть соединение с базой данных.
Вся текущая активность в удаляемом соединении немедленно прекращается, и все активные транзакции откатываются (триггеры на события ON DISCONNECT и ON TRANSACTION ROLLBACK не вызываются);
Закрытое соединение вернёт приложению ошибку с кодом isc_att_shutdown;
Последующие попытки использовать это соединение (т.е. использовать его handle в API-вызовах) вернут ошибки;
Завершение системных соединений (MON$SYSTEM_FLAG = 1) невозможно. Сервер пропустит системные подключения затронутые оператором DELETE FROM MON$ATTACHMENTS.
Примеры:
Пример E.1. Получение сведений о клиентских приложениях
SELECT MON$USER, MON$REMOTE_ADDRESS, MON$REMOTE_PID, MON$TIMESTAMP FROM MON$ATTACHMENTS WHERE MON$ATTACHMENT_ID <> CURRENT_CONNECTION
Пример E.2. Отключение всех соединений, за исключением своего
DELETE FROM MON$ATTACHMENTS WHERE MON$ATTACHMENT_ID <> CURRENT_CONNECTION
Обращения к стеку запросами хранимых процедур, хранимых функций и триггеров.
Таблица E.3. Описание столбцов таблицы MON$CALL_STACK
Наименование столбца | Тип данных | Описание |
---|---|---|
MON$CALL_ID | INTEGER | Идентификатор обращения. |
MON$STATEMENT_ID | INTEGER | Идентификатор верхнего уровня оператора SQL — оператора, инициировавшего цепочку обращений. По этому идентификатору можно найти запись об активном операторе в таблице MON$STATEMENTS. |
MON$CALLER_ID | INTEGER | Идентификатор обращающегося триггера, хранимой функции или хранимой процедуры. |
MON$OBJECT_NAME | CHAR(31) | Имя объекта PSQL. |
MON$OBJECT_TYPE | SMALLINT |
Тип объекта PSQL:
|
MON$TIMESTAMP | TIMESTAMP | Дата и время старта обращения. |
MON$SOURCE_LINE | INTEGER | Номер исходной строки оператора SQL, выполняющегося в настоящий момент. |
MON$SOURCE_COLUMN | INTEGER | Номер исходного столбца оператора SQL, выполняющегося в настоящий момент. |
MON$STAT_ID | INTEGER | Идентификатор статистики. |
В стек вызовов не попадёт информация о вызовах при выполнении оператора EXECUTE STATEMENT.
Примеры:
Пример E.3. Получение стека вызовов для всех подключений кроме своего
WITH RECURSIVE HEAD AS ( SELECT CALL.MON$STATEMENT_ID, CALL.MON$CALL_ID, CALL.MON$OBJECT_NAME, CALL.MON$OBJECT_TYPE FROM MON$CALL_STACK CALL WHERE CALL.MON$CALLER_ID IS NULL UNION ALL SELECT CALL.MON$STATEMENT_ID, CALL.MON$CALL_ID, CALL.MON$OBJECT_NAME, CALL.MON$OBJECT_TYPE FROM MON$CALL_STACK CALL JOIN HEAD ON CALL.MON$CALLER_ID = HEAD.MON$CALL_ID ) SELECT MON$ATTACHMENT_ID, MON$OBJECT_NAME, MON$OBJECT_TYPE FROM HEAD JOIN MON$STATEMENTS STMT ON STMT.MON$STATEMENT_ID = HEAD.MON$STATEMENT_ID WHERE STMT.MON$ATTACHMENT_ID <> CURRENT_CONNECTION
Сведения о пользовательских контекстных переменных.
Таблица E.4. Описание столбцов таблицы MON$CONTEXT_VARIABLES
Наименование столбца | Тип данных | Описание |
---|---|---|
MON$ATTACHMENT_ID | INTEGER | Идентификатор соединения. Содержит корректное значение только для контекстных переменных уровня соединения, для переменных уровня транзакции устанавливается в NULL. |
MON$TRANSACTION_ID | INTEGER | Идентификатор транзакции. Содержит корректное значение только для контекстных переменных уровня транзакции, для переменных уровня соединения устанавливается в NULL. |
MON$VARIABLE_NAME | VARCHAR(80) | Имя контекстной переменной. |
MON$VARIABLE_VALUE | VARCHAR(255) | Значение контекстной переменной. |
Примеры:
Пример E.4. Получение всех сессионных контекстных переменных для текущего подключения
SELECT VAR.MON$VARIABLE_NAME, VAR.MON$VARIABLE_VALUE FROM MON$CONTEXT_VARIABLES VAR WHERE VAR.MON$ATTACHMENT_ID = CURRENT_CONNECTION
Сведения о базе данных, с которой выполнено соединение.
Таблица E.5. Описание столбцов таблицы MON$DATABASE
Наименование столбца | Тип данных | Описание |
---|---|---|
MON$DATABASE_NAME | VARCHAR(255) | Полный путь и имя первичного файла базы данных или псевдоним базы данных. |
MON$PAGE_SIZE | SMALLINT | Размер страницы файлов базы данных в байтах. |
MON$ODS_MAJOR | SMALLINT | Старшая версия ODS. |
MON$ODS_MINOR | SMALLINT | Младшая версия ODS. |
MON$OLDEST_TRANSACTION | INTEGER | Номер старейшей заинтересованной транзакции — OIT, Oldest Interesting Transaction. |
MON$OLDEST_ACTIVE | INTEGER | Номер старейшей активной транзакции — OAT, Oldest Active Transaction. |
MON$OLDEST_SNAPSHOT | INTEGER | Номер транзакции, которая была активной на момент старта транзакции OAT, транзакция OST — Oldest Snapshot Transaction. |
MON$NEXT_TRANSACTION | INTEGER | Номер следующей транзакции. |
MON$PAGE_BUFFERS | INTEGER | Количество страниц, выделенных в оперативной памяти для кэша. |
MON$SQL_DIALECT | SMALLINT | SQL диалект базы данных: 1 или 3. |
MON$SHUTDOWN_MODE | SMALLINT |
Текущее состояние останова (shutdown) базы данных:
|
MON$SWEEP_INTERVAL | INTEGER | Интервал чистки (sweep interval). |
MON$READ_ONLY | SMALLINT | Признак, является база данных только для чтения, read only, (значение 1) или для чтения и записи, read-write (0). |
MON$FORCED_WRITES | SMALLINT | Указывает, установлен ли для базы режим синхронного вывода (forced writes, значение 1) или режим асинхронного вывода (значение 0). |
MON$RESERVE_SPACE | SMALLINT | Флаг, указывающий на резервирование пространства. |
MON$CREATION_DATE | TIMESTAMP | Дата и время создания базы данных. |
MON$PAGES | BIGINT | Количество страниц, выделенных для базы данных на внешнем устройстве. |
MON$STAT_ID | INTEGER | Идентификатор статистики. |
MON$BACKUP_STATE | SMALLINT |
Текущее физическое состояние backup:
|
Статистика по вводу-выводу.
Таблица E.6. Описание столбцов таблицы MON$IO_STATS
Наименование столбца | Тип данных | Описание |
---|---|---|
MON$STAT_ID | INTEGER | Идентификатор статистики. |
MON$STAT_GROUP | SMALLINT |
Группа статистики:
|
MON$PAGE_READS | BIGINT | Количество прочитанных (read) страниц базы данных. |
MON$PAGE_WRITES | BIGINT | Количество записанных (write) страниц базы данных. |
MON$PAGE_FETCHES | BIGINT | Количество загруженных в память (fetch) страниц базы данных. |
MON$PAGE_MARKS | BIGINT | Количество отмеченных (mark) страниц базы данных. |
Счётчики этой таблицы являются накопительными и накапливают информацию по каждой из групп статистики.
Статистика использования памяти.
Таблица E.7. Описание столбцов таблицы MON$MEMORY_USAGE
Наименование столбца | Тип данных | Описание |
---|---|---|
MON$STAT_ID | INTEGER | Идентификатор статистики. |
MON$STAT_GROUP | SMALLINT |
Группа статистики:
|
MON$MEMORY_USED | BIGINT |
Количество используемой памяти, байт. Информация о высокоуровневом распределении памяти, выполненной сервером из пулов. Может быть полезна для отслеживания утечек памяти и чрезмерного потребления памяти в соединениях, процедурах и т.д. |
MON$MEMORY_ALLOCATED | BIGINT |
Количество памяти, выделенной ОС, байт. Информация о низкоуровневом распределении памяти, выполненном менеджером памяти Firebird — объем памяти, выделенный операционной системой, что позволяет контролировать физическое потребление памяти. Обратите внимание, не все записи этого столбца имеют ненулевые значения. Малые выделения памяти здесь не фиксируются, а вместо этого добавляются к пулу памяти базы данных. Только MON$DATABASE (MON$STAT_GROUP = 0) и связанные с выделением памяти объекты имеют ненулевое значение. |
MON$MAX_MEMORY_USED | BIGINT | Максимальное количество байт, используемое данным объектом. |
MON$MAX_MEMORY_ALLOCATED | BIGINT | Максимальное количество байт, выделенное ОС данному объекту. |
Счётчики, связанные с записями уровня базы данных MON$DATABASE (MON$STAT_GROUP = 0), отображают выделение памяти для всех соединений. В архитектурах Classic и SuperClassic нулевые значения счётчиков обозначают, что в этих архитектурах нет общего кэша.
Примеры:
Пример E.5. Получение 10 запросов потребляющих наибольшее количество памяти
SELECT STMT.MON$ATTACHMENT_ID, STMT.MON$SQL_TEXT, MEM.MON$MEMORY_USED
FROM MON$MEMORY_USAGE MEM
NATURAL JOIN MON$STATEMENTS STMT
ORDER BY MEM.MON$MEMORY_USED DESC
FETCH FIRST 10 ROWS ONLY
Статистика на уровне записей.
Таблица E.8. Описание столбцов таблицы MON$RECORD_STATS
Наименование столбца | Тип данных | Описание |
---|---|---|
MON$STAT_ID | INTEGER | Идентификатор статистики. |
MON$STAT_GROUP | SMALLINT |
Группа статистики:
|
MON$RECORD_SEQ_READS | BIGINT | Количество последовательно считанных записей (read sequentially). |
MON$RECORD_IDX_READS | BIGINT | Количество записей, прочитанных при помощи индекса (read via an index). |
MON$RECORD_INSERTS | BIGINT | Количество добавленных записей (inserted records). |
MON$RECORD_UPDATES | BIGINT | Количество изменённых записей (updated records). |
MON$RECORD_DELETES | BIGINT | Количество удалённых записей (deleted records). |
MON$RECORD_BACKOUTS | BIGINT | Количество возвращённых в базу данных записей (backed out records). |
MON$RECORD_PURGES | BIGINT | Количество удалённых ненужных записей (purged records). |
MON$RECORD_EXPUNGES | BIGINT | Количество вычищенных средствами сборки мусора записей (expunged records). |
Счётчики этой таблицы являются накопительными и накапливают информацию по каждой из групп статистики.
Подготовленные к выполнению операторы.
Таблица E.9. Описание столбцов таблицы MON$STATEMENTS
Наименование столбца | Тип данных | Описание |
---|---|---|
MON$STATEMENT_ID | INTEGER | Идентификатор оператора. |
MON$ATTACHMENT_ID | INTEGER | Идентификатор соединения. |
MON$TRANSACTION_ID | INTEGER | Идентификатор транзакции. |
MON$STATE | SMALLINT |
Состояние оператора:
|
MON$TIMESTAMP | TIMESTAMP | Дата и время старта оператора. |
MON$SQL_TEXT | BLOB TEXT | Текст оператора на языке SQL. |
MON$STAT_ID | INTEGER | Идентификатор статистики. |
Состояние оператора STALLED — это состояние "приостановлено". Возможно для запроса, который начал своё выполнение, ещё не завершил его, но в данный момент не выполняется. Например, ждёт входных параметров или очередного фетча (fetch) от клиента.
Таблицы мониторинга доступны только для чтения. Однако в сервер встроен механизм для удаления (и только удаления) записей в таблице MON$STATEMENTS, что позволяет завершить активный запрос.
Попытка отмены запросов не выполняется, если в соединении в настоящее время нет никаких выполняющихся операторов.
После отмены запроса вызов API-функций execute/fetch вернёт ошибку с кодом isc_cancelled.
Последующие запросы в данном соединении не запрещёны.
Отмена запроса не происходит синхронно, оператор лишь помечает запрос на отмену, а сама отмена производится ядром асинхронно.
Примеры:
Пример E.6. Отображение активных запросов за исключением тех, что выполняются в своём соединении
SELECT ATT.MON$USER, ATT.MON$REMOTE_ADDRESS, STMT.MON$SQL_TEXT, STMT.MON$TIMESTAMP
FROM MON$ATTACHMENTS ATT
JOIN MON$STATEMENTS STMT ON ATT.MON$ATTACHMENT_ID = STMT.MON$ATTACHMENT_ID
WHERE ATT.MON$ATTACHMENT_ID <> CURRENT_CONNECTION
AND STMT.MON$STATE = 1
Пример E.7. Отмена всех активных запросов для заданного соединения
DELETE FROM MON$STATEMENTS
WHERE MON$ATTACHMENT_ID = 32
Описывает запущенные на выполнение транзакции
Таблица E.10. Описание столбцов таблицы MON$TRANSACTIONS
Наименование столбца | Тип данных | Описание |
---|---|---|
MON$TRANSACTION_ID | INTEGER | Идентификатор (номер) транзакции. |
MON$ATTACHMENT_ID | INTEGER | Идентификатор соединения. |
MON$STATE | SMALLINT |
Состояние транзакции:
Запрос связывается с транзакцией, когда начинает его выполнение. Эта связь разрывается когда запрос начинает новое выполнение в другой транзакции, или когда транзакция или запрос удаляется, но не тогда, когда запрос выполнен или из курсора выбраны все записи. |
MON$TIMESTAMP | TIMESTAMP | Дата и время старта транзакции. |
MON$TOP_TRANSACTION | INTEGER | Верхний предел используемый транзакцией чистильщика (sweeper) при продвижении глобального OIT. Все транзакции выше этого порога считаются активными. Обычно он эквивалентен MON$TRANSACTION_ID, но использование COMMIT RETAINING или ROLLBACK RETAINING приводит к тому, что MON$TOP_TRANSACTION останется неизменным ("зависшим") при увеличении идентификатора транзакции. |
MON$OLDEST_TRANSACTION | INTEGER | Номер старейшей заинтересованной транзакции — OIT, Oldest Interesting Transaction. |
MON$OLDEST_ACTIVE | INTEGER | Номер старейшей активной транзакции — OAT, Oldest Active Transaction. |
MON$ISOLATION_MODE | SMALLINT |
Режим (уровень) изоляции:
|
MON$LOCK_TIMEOUT | SMALLINT |
Время ожидания:
|
MON$READ_ONLY | SMALLINT | Признак, является ли транзакцией только для чтения, read only (значение 1) или для чтения и записи, read-write (0). |
MON$AUTO_COMMIT | SMALLINT | Признак, используется ли автоматическое подтверждение транзакции auto-commit (значение 1) или нет (0). |
MON$AUTO_UNDO | SMALLINT | Признак, используется ли автоматическая отмена транзакции auto-undo (значение 1) или нет (0). Если используется автоматическая отмена транзакции, создаётся точка сохранения уровня транзакции. Существование точки сохранения позволяет отменять изменения, если вызывается ROLLBACK, после чего транзакция просто фиксируется. Если этой точки сохранения не существует или она существует, но количество изменений очень велико, выполняется фактический ROLLBACK, и транзакция помечается в TIP как «мертвая». |
MON$STAT_ID | INTEGER | Идентификатор статистики. |
Примеры:
Пример E.8. Получение уровня изолированности текущей транзакций
SELECT MON$ISOLATION_MODE FROM MON$TRANSACTIONS WHERE MON$TRANSACTION_ID = CURRENT_TRANSACTION
Таблица F.1. Наборы символов и порядки сортировки
Название | ID | Байтов на символ | Порядок сортировки | Язык |
---|---|---|---|---|
ASCII | 2 | 1 | ASCII | Английский |
BIG_5 | 56 | 2 | BIG_5 |
Китайский, Вьетнамский, Корейский. |
CP943C | 68 | 2 | CP943C | Японский. |
CP943C_UNICODE | Японский. | |||
CYRL | 50 | 1 | CYRL | Русский. |
DB_RUS | Русский dBase. | |||
PDOX_CYRL | Русский Paradox. | |||
DOS437 | 10 | 1 | DOS437 | Английский — США. |
DB_DEU437 | Немецкий dBase. | |||
DB_ESP437 | Испанский dBase. | |||
DB_FIN437 | Финский dBase. | |||
DB_FRA437 | Французский dBase. | |||
DB_ITA437 | Итальянский dBase. | |||
DB_NLD437 | Голландский dBase. | |||
DB_SVE437 | Шведский dBase. | |||
DB_UK437 | Английский (Великобритания) dBase. | |||
DB_US437 | Английский (США) dBase. | |||
PDOX_ASCII | Кодовая страница Paradox — ASCII. | |||
PDOX_SWEDFIN | Шведский / Финский Paradox. | |||
PDOX_INTL | Международный английский Paradox. | |||
DOS737 | 9 | 1 | DOS737 | Греческий. |
DOS775 | 15 | 1 | DOS775 | Балтийский. |
DOS850 | 11 | 1 | DOS850 | Латинский I (нет символа Евро). |
DB_DEU850 | Немецкий. | |||
DB_ESP850 | Испанский. | |||
DB_FRA850 | Французский. | |||
DB_FRC850 | Французский — Канада. | |||
DB_ITA850 | Итальянский. | |||
DB_NLD850 | Голландский. | |||
DB_PTB850 | Португальский — Бразилия. | |||
DB_SVE850 | Шведский. | |||
DB_UK850 | Английский — Великобритания. | |||
DB_US850 | Английский — США. | |||
DOS852 | 45 | 1 | DOS852 | Латинский II. |
DB_CSY | Чешский dBase. | |||
DB_PLK | Польский dBase. | |||
DB_SLO | Словацкий dBase. | |||
PDOX_CSY | Чешский Paradox. | |||
PDOX_HUN | Венгерский Paradox. | |||
PDOX_PLK | Польский Paradox. | |||
PDOX_SLO | Словацкий Paradox. | |||
DOS857 | 46 | 1 | DOS857 | Турецкий. |
DB_TRK | Турецкий dBase. | |||
DOS858 | 16 | 1 | DOS858 | Латинский I с символом Евро. |
DOS860 | 13 | 1 | DOS860 | Португальский. |
DB_PTG860 | Португальский dBase. | |||
DOS861 | 47 | 1 | DOS861 | Исландский. |
PDOX_ISL | Исландский Paradox. | |||
DOS862 | 17 | 1 | DOS862 | Иврит. |
DOS863 | 14 | 1 | DOS863 | Французский — Канада. |
DB_FRC863 | Французский dBase — Канада. | |||
DOS864 | 18 | 1 | DOS864 | Арабский. |
DOS865 | 12 | 1 | DOS865 | Скандинавские. |
DB_DAN865 | Датский dBase. | |||
DB_NOR865 | Норвежский dBase. | |||
PDOX_NORDAN4 | Paradox Норвегия и Дания. | |||
DOS866 | 48 | 1 | DOS866 | Русский. |
DOS869 | 49 | 1 | DOS869 | Современный греческий. |
EUCJ_0208 | 6 | 2 | EUCJ_0208 | Японские EUC. |
GB_2312 | 57 | 2 | GB_2312 | Упрощенный китайский (Гонконг, Корея). |
GB18030 | 69 | 4 | GB18030 | Китайский. |
GB18030_UNICODE | Китайский. | |||
GBK | 67 | 2 | GBK | Китайский. |
GBK_UNICODE | Китайский. | |||
ISO8859_1 | 21 | 1 | ISO8859_1 | Латинский I. |
DA_DA | Датский. | |||
DE_DE | Немецкий. | |||
DU_NL | Голландский. | |||
EN_UK | Английский, Великобритания. | |||
EN_US | Английский, США. | |||
ES_ES | Испанский. | |||
ES_ES_CI_AI | Испанский не чувствительный к регистру символов и к акцентам (ударению). | |||
FI_FI | Финский. | |||
FR_CA | Французский, Канада. | |||
FR_FR | Французский. | |||
FR_FR_CI_AI | Французский — не чувствительный к регистру символов и к акцентам (ударению). | |||
IS_IS | Исландский. | |||
IT_IT | Итальянский. | |||
NO_NO | Норвежский. | |||
PT_PT | Португальский. | |||
PT_BR | Португальский, Бразилия. | |||
SV_SV | Шведский. | |||
ISO8859_2 | 22 | 1 | ISO8859_2 | Латинский 2 — Центральная Европа (хорватский, чешский, венгерский, польский, румынский, сербский, словацкий, словенский). |
CS_CZ | Чешский. | |||
ISO_HUN | Венгерский — не чувствительный к регистру и чувствительный к акценту (ударению). | |||
ISO_PLK | Польский. | |||
ISO8859_3 | 23 | 1 | ISO8859_3 | Латинский 3 — Южная Европа (мальтийский, эсперанто). |
ISO8859_4 | 34 | 1 | ISO8859_4 | Латинский 4 — Северная Европа (эстонский, латвийский, литовский, гренландский, саамский). |
ISO8859_5 | 35 | 1 | ISO8859_5 | Кириллица (русский). |
ISO8859_6 | 36 | 1 | ISO8859_6 | Арабский. |
ISO8859_7 | 37 | 1 | ISO8859_7 | Греческий. |
ISO8859_8 | 38 | 1 | ISO8859_8 | Иврит. |
ISO8859_9 | 39 | 1 | ISO8859_9 | Латинский 5. |
ISO8859_13 | 40 | 1 | ISO8859_13 | Латинский 7 — Балтика. |
LT_LT | Литовский. | |||
KOI8R | 63 | 1 | KOI8R | Русский. Словарное упорядочение. |
KOI8R_RU | Русский. | |||
KOI8U | 64 | 1 | KOI8U | Украинский. Словарное упорядочение. |
KOI8U_UA | Украинский. | |||
KSC_5601 | 44 | 2 | KSC_5601 | Корейский. |
KSC_DICTIONARY | Корейский — словарный порядок сортировки. | |||
NEXT | 19 | 1 | NEXT | Кодирование NeXTSTEP. |
NXT_DEU | Немецкий. | |||
NXT_ESP | Испанский. | |||
NXT_FRA | Французский. | |||
NXT_ITA | Итальянский. | |||
NXT_US | Английский, США. | |||
NONE | 0 | 1 | NONE | Нейтральная кодовая страница. Перевод в верхний регистр выполняется только для кодов ASCII 97–122. Постарайтесь сделать так, чтобы этот набор символов никогда не появлялся в столбцах ваших баз данных. |
OCTETS | 1 | 1 | OCTETS | Двоичные символы. |
SJIS_0208 | 5 | 2 | SJIS_0208 | Японский. |
TIS620 | 66 | 1 | TIS620 | Тайский. |
TIS620_UNICODE | Тайский. | |||
UNICODE_FSS | 3 | 3 | UNICODE_FSS | UNICODE |
UTF8 | 4 | 4 | UTF8 | UNICODE 4.0. |
USC_BASIC | UNICODE 4.0. | |||
UNICODE | UNICODE 4.0. | |||
UNICODE_CI | UNICODE 4.0. Не чувствительна к регистру символов. | |||
UNICODE_CI_AI | UNICODE 4.0. Не чувствительна к регистру символов и к акцентам (ударению). | |||
WIN1250 | 51 | 1 | WIN1250 | ANSI — Центральная Европа. |
BS_BA | Боснийский. | |||
PXW_CSY | Чешский. | |||
PXW_HUN | Венгерский — не чувствительный к регистру и чувствительный к акценту (ударению). | |||
PXW_HUNDC | Венгерский — словарная сортировка. | |||
PXW_PLK | Польский. | |||
PXW_SLOV | Словенский. | |||
WIN_CZ | Чешский. | |||
WIN_CZ_CI | Чешский без различия строчных и прописных букв. | |||
WIN_CZ_CI_AI | Чешский без различия строчных и прописных букв, нечувствительный к знакам ударения. | |||
WIN1251 | 52 | 1 | WIN1251 | ANSI кириллица. |
WIN1251_UA | Украинский. | |||
PXW_CYRL | Paradox кириллица (русский). | |||
WIN1252 | 53 | 1 | WIN1252 | ANSI — Латинский I. |
PXW_INTL | Английский интернациональный. | |||
PXW_INTL850 | Paradox многоязыковый Латинский I. | |||
PXW_NORDAN4 | Норвежский и датский. | |||
PXW_SPAN | Paradox испанский. | |||
PXW_SWEDFIN | Шведский и финский. | |||
WIN_PTBR | Португальский, Бразилия. | |||
WIN1253 | 54 | 1 | WIN1253 | ANSI греческий. |
PXW_GREEK | Paradox греческий. | |||
WIN1254 | 55 | 1 | WIN1254 | ANSI турецкий. |
PXW_TURK | Paradox турецкий. | |||
WIN1255 | 58 | 1 | WIN1255 | ANSI иврит. |
WIN1256 | 59 | 1 | WIN1256 | ANSI арабский. |
WIN1257 | 60 | 1 | WIN1257 | ANSI балтийский. |
WIN1257_EE | Эстонский. Словарное упорядочение. | |||
WIN1257_LT | Литовский. Словарное упорядочение. | |||
WIN1257_LV | Латвийский. Словарное упорядочение. | |||
WIN1258 | 65 | 1 | WIN1258 | Вьетнамский. |
Содержание данного Документа распространяется на условиях лицензии «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) 2016. Все права защищены. Адрес электронной почты для контакта:
<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).
Руководство по языку SQL СУБД Firebird 2.5 | Firebird |