Распространенная ошибка предполагать, что значение по умолчанию будет использовано, когда Firebird получает значение NULL в столбце, имеющем значение по умолчанию. Чтобы быть уверенным в правильном использовании значений по умолчанию, нужно понимать, что значение по умолчанию будет применено:
* только при добавлении новой строки;
* только если оператор INSERT не включает столбец со значением по умолчанию в списке столбцов.
Если ваше приложение содержит столбец, имеющий значение по умолчанию, в операторе INSERT и передает NULL в списке значений, то будет сохраняться значение NULL или будет вызвано исключение для столбца, не допускающего пустое значение, независимо от наличия значения по умолчанию.
Атрибут NOT NULL
Включите этот атрибут в описание домена, если вы хотите, чтобы все столбцы, создаваемые на основе этого домена, имели непустое значение.
NULL - который является не значением, а состоянием, - всегда будет недопустимым для любого столбца, имеющего атрибут NOT NULL. Детальное обсуждение NULL см. в разд. "Рассмотрение NULL" главы 21.
! ! !
ВНИМАНИЕ! Вы не можете переопределить атрибут NOT NULL для домена. Рассмотрите преимущества невключения его в состав атрибутов домена, оставляя, таким образом, возможность добавить этот атрибут при определении столбца.
. ! .
Условия CHECK
Ограничение CHECK предоставляет атрибуты домена, ограничивающие содержимое данных, которое может быть сохранено в столбцах, использующих домен. Ограничение CHECK задает условие поиска (условие-поиска-домена), которое должно быть истинным до того, как данные могут быть помещены в эти столбцы.
Вот синтаксис ограничений CHECK:
<условие-поиска-домена> =
VALUE <оператор>
| VALUE [NOT] BETWEEN
| VALUE [NOT] LIKE
| VALUE [NOT] IN (
| VALUE IS [NOT] NULL
| VALUE [NOT] CONTAINING
| VALUE [NOT] STARTING [WITH]
I(<условие-поиска-домена>)
I NOT<условие-поиска-домена>
<условие-поиска-домена> OR <условие-поиска-домена>
| <условие-поиска-домена> AND <условие-поиска-домена>
<оператор> ={=|<|>I<=|>=|!<|!>|<>|!=}
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, однако множество условий может быть включено в это предложение с помощью операторов 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 могут содержать выражения, ссылающиеся на другие столбцы в той же самой таблице или (что менее желательно) ссылающиеся на другие объекты базы данных (таблицы, хранимые процедуры).