Книга: Firebird РУКОВОДСТВО РАЗРАБОТЧИКА БАЗ ДАННЫХ

Условия CHECK

Условия CHECK

Ограничение CHECK предоставляет атрибуты домена, ограничивающие содержимое данных, которое может быть сохранено в столбцах, использующих домен. Ограничение CHECK задает условие поиска (условие-поиска-домена), которое должно быть истинным до того, как данные могут быть помещены в эти столбцы.

Вот синтаксис ограничений CHECK:

<условие-поиска-домена> =

VALUE <оператор> <val>

| VALUE [NOT] BETWEEN <val> AND <val>

| VALUE [NOT] LIKE <val> [ESCAPE <val>]

| VALUE [NOT] IN (<val> [, <val> ...])

| VALUE IS [NOT] NULL

| VALUE [NOT] CONTAINING <val>

| VALUE [NOT] STARTING [WITH] <val>

I(<условие-поиска-домена>)

I NOT<условие-поиска-домена>

<условие-поиска-домена> OR <условие-поиска-домена>

| <условие-поиска-домена> AND <условие-поиска-домена>

<оператор> ={=|<|>I<=|>=|!<|!>|<>|!=}

Ключевое слово VALUE

VALUE является заполнителем для любой константы, значения переменной или результата выражения, которые могут быть подставлены в синтаксисе SQL для сохранения данных в столбце, использующем домен. Ограничение CHECK указывает, что VALUE должно проверяться на ограничения, определенные в условиях. Если проверка не соответствует, то вызывается исключение.

Если значение NULL допустимо, то правило должно учитывать этот факт в ограничении CHECK, например:

CHECK ((VALUE IS NULL) OR(VALUE > 1000));

Следующий оператор создает домен, который запрещает вводить значение 1000 и меньше, при этом он также неявно запрещает NULL во множестве допустимых значений:

CREATE DOMAIN CUSTNO

AS INTEGER

CHECK(VALUE > 1000);

Следующий оператор ограничивает VALUE одним из четырех заданных значений:

CREATE DOMAIN PRODTYPE

AS VARCHAR(8) NOT NULL

CHECK(VALUE IN ('software', 'hardware', 'other', 'N/A'));

Условие проверки может быть выполнено в виде поиска указанного шаблона во вводимой строке. Например, следующее правило проверяет наличие круглых скобок в коде региона (например, (09)438894749):

CREATE DOMAIN TEL_NUMBER

AS VARCHAR (18)

CHECK(VALUE LIKE '(0%)%');

Подробнее о строковых шаблонах, которые вы можете использовать в выражениях, см. в примечаниях к оператору LIKE в разд. "Операторы SQL" главы 21.

Множество условий CHECK

Домен может иметь только одно предложение CHECK, однако множество условий может быть включено в это предложение с помощью операторов AND (И - конъюнкция) и OR (ИЛИ - дизъюнкция). Позаботьтесь о необходимых скобках в выражениях условий, чтобы исключить получение логических исключений при подготовке оператора DDL.

Например, следующий оператор будет ошибочным:

create domain rhubarb as varchar(20)

check(VALUE is not null) and(VALUE starting with 'J');

Он вызовет исключение с сообщением "token unknown" на слове "and". Правильный оператор заключает весь список условий во внешние скобки:

create domain rhubarb as varchar(20)

check ((value is not null) and(VALUE starting with 'J'));

! ! !

ПРИМЕЧАНИЕ. Предыдущий оператор проверяет, чтобы входное значение не было NULL. Это замечательно, однако использование ограничения NOT NULL напрямую является более мощным средством для интерфейса приложения. API может информировать клиентское приложение во время подготовки (prepare) об ограничении NOT NULL, В ТО время как триггеры проверки CHECK не будут вызываться, пока запрос DML не будет фактически отправлен на сервер.

. ! .

Подробности о STARTING WITH и других используемых в выражениях операторах SQL см. в главе 21.

Ограничение CHECK не может быть переопределено в определении столбца, хотя столбец может расширить использование ограничения CHECK домена, добавив свои собственные условия.

Зависимости в ограничениях CHECK

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

Конечно, домены не могут ссылаться на другие домены. При этом почти всегда возможно неудачное решение определять домен, который ссылается на столбец существующей таблицы. Например:

create domain rather_silly as char(3)

check(VALUE in (select substring(registration from 1 for 3)

from aircraft));

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

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

Отношения внешнего ключа существуют повсюду, в то время как область действия условия CHECK ограничивается вводом данных.

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

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

! ! !

СОВЕТ. Другим пониманием данной техники является сложность (или невозможность) для вспомогательных программ извлекать непробиваемые бомбами скрипты SQL из системных таблиц. Может наступить такое время, когда ваша работа усложнится из-за необходимости правильного извлечения скриптов SQL из базы данных!

. ! .

Если вам совершенно необходимо использовать этот вид условий проверки, обратитесь к дополнительным условиям при объявлении столбца. Лучше оцените все альтернативы- включая ручное кодирование ссылочных триггеров в случаях, когда внешние ключи для ссылочных полей приведут к проблемам избирательности (селективности) индексов[30].

Оглавление книги


Генерация: 0.488. Запросов К БД/Cache: 3 / 0
поделиться
Вверх Вниз