21. Создание доменов

21.1. Понятие домена

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

Например, создать домен POL_TYPE и затем использовать его при создании таблицы SOTR как тип столбца POL:

CREATE DOMAIN POL_TYPE AS

CHAR(3) COLLATE PXW_CYRL;

CREATE TABLE SOTR(

FIO CHAR(20) NOT NULL,

POL POL_TYPE,

OTDEL CHAR(10),

DOLJ CHAR(20),

PRIMARY KEY(FIO)

) ;

Как можно заметить, домен есть описание какого-либо столбца, то есть абстрактное понятие; как такового домена физически не существует. В языке Object Pascal сходным по назначению с определением домена является определение типа в блоке type; фактически определение типа не приводит к выделению памяти под переменную, но может использоваться при объявлении переменных в блоке var. Для приведенного выше примера, домена POL_TYPE как структуры данных физически нет, поскольку им невозможно воспользоваться для хранения данных и доступа к ним. Однако физически существует и доступен для хранения и доступа к данным столбец POL в таблице SOTR, при создании которого было использовано описание домена POL_TYPE.

Домен определяется оператором CREATE DOMAIN. Его формат:

CREATE DOMAIN домен [AS] <тип_данных>

[DEFAULT {литерал| NULL | USER}]

[NOT NULL] [CHECK (<усл_поиска_домена>)]

[COLLATE collation] ;

Предложение COLLATE позволяет указать порядок сортировки символов, например:

CREATE DOMAIN POL_TYPE AS

CHAR(3) COLLATE PXW_CYRL;

Предложение DEFAULT определяет оператор, который по умолчанию заносится в колонку, ассоциированную с доменом, при создании записи таблицы. Это значение будет присутствовать в соответствующем столбце данной записи до тех пор, пока пользователь не изменит его каким-либо образом. Значения по умолчанию могут быть выражены как:

литерал- значение (числовое, строковое или дата);

NULL - специфицирует пустое значение;

• USER - имя текущего пользователя.

Заметим, что значения по умолчанию, присваиваемые данному столбцу и объявленные в операторах CREATE TABLE или ALTER TABLE, переопределяют значения, присваиваемые по умолчанию тому же столбцу согласно директивам, содержащимся в CREATE DOMAIN.

Предложение NOT NULL указывает, что столбцы, ассоциированные с доменом, обязательно должны содержать какое-либо значение, отличное от пустого. Нужно следить за тем, чтобы в объявлении домена не было противоречий, например, в описании значения по умолчанию как NULL и объявлении директивы NOT NULL.

21.2. Ограничения на значения столбцов, ассоциированных с доменом

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

<огранич_домена> = {

VALUE <оператор> <значение>

| VALUE [NOT] BETWEEN <значение1> AND <значение2>

| VALUE [NOT] LIKE <значение> [ESCAPE <значение>]

| VALUE [NOT] IN (<значение1> [, <значение2> ...]) VALUE IS [NOT] NULL

| VALUE [NOT] CONTAINING <значение>

| VALUE [NOT] STARTING [WITH] <значение>

| (<огранич домена>) | NOT <огранич домена>

| <огранич_домена> ОR<огранич_домена> | <огранич домена> AND <огранич_домена>

}

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

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

• VALUE <оператор> <значение> определяет, что значение домена находится с параметром значение во взаимоотношениях, определяемых параметром оператор.

Например, значение, которое может быть записано в столбец, ассоциированный с доменом ID_TYPE, должно быть больше или равно 100:

CREATE DOMAIN ID_TYPE AS INTEGER CHECK(VALUE >= 100);

• BETWEEN <значение1> AND <значение2> определяет, что значение домена должно находиться в промежутке между значение! и значение!, включая их;

• LIKE <значение1> [ESCAPE <значение2>1 определяет, что значение домена должно "походить" на параметр значение!. При этом употребляется символ '%' для указания любого значения любой длины и символ '_' (подчеркивания) для указания любого единичного символа. Например,

LIKE "%USD" - вводимое значение должно оканчиваться символами 'USD', независимо от того, какие символы и сколько расположены перед ними;

LIKE "_94" - вводимое значение может содержать 4 символа, из которых первые два - любые и последние два - '94'.

ESCAPE <значение2> используется, если в операторе LIKE символы '%' или '_' должны использоваться в шаблоне подобия. В этом случае выбирается некоторый символ, например "!", после которого символы '%', '_' входят в поисковую строку как непосредственно символы. Символ Т указывается после слова ESCAPE, например:

CREATE DOMAIN SUMMA AS CHAR(lO) CHECK(LIKE "%!%" ESCAPE "!");

Значения столбца SUMMA должны заканчиваться символом "%".

• IN (<значение1 > [, <значение2>...]) определяет, что значение домена должно совпадать с одним из приведенных в списке параметров значение Х,, например:

CREATE DOMAIN POL_TYPE AS CHAR(3) CHECK(VALUE IN ("Муж","Жен"));

• CONTAINING <значение> определяет, что значение домена должно содержать вхождение параметра значение, неважно в каком месте. Например, в наименовании отдела вхождение "041" может встретиться где угодно ("Отдел-041002", "003404192", и т.д.):

CREATE DOMAIN OTDEL_TYPE AS VARCHAR(lO) CHECK(VALUE CONTAINING "041") COLLATE

PXW_CYRL;

STARTING [WITH] <значение> требует, чтобы значение домена начиналось параметром значение. Например, название отдела должно начинаться с "041":

CREATE DOMAIN OTDEL_TYPE AS VARCHAR(lO) CHECK(VALUE STARTING WITH "041")

COLLATE PXW_CYRL;

• Может быть задана комбинация условий, которым должно соответствовать значение домена. В этом случае отдельные условия соединяются операторами AND или OR. Например:

CREATE DOMAIN OTDEL_TYPE AS VARCHAR(lO) CHECK(VALUE STARTING WITH "041" AND

VALUE CONTAINING "-12") COLLATE PXW_CYRL;

• Для большинства условий можно указать слово NOT, которое изменит условие с точностью до наоборот. Например: CHECK(VALUE NOT BETWEEN 1 AND 100);

21.3. Изменение определения домена

Оператор

ALTER DOMAIN имя {

[SET DEFAULT {литерал] NULL | USER}]

| [DROP DEFAULT] | [ADD [CONSTRAINT] CHECK (<огранич_домена>)] | [DROP CONSTRAINT]

};

позволяет изменить параметры домена, определенного ранее оператором CREATE DOMAIN. Однако нельзя изменить тип данных и определение NOT NULL. Следует помнить, что все сделанные изменения будут учтены для всех столбцов, определенных с использованием данного домена (в том случае, если параметры домена не были переопределены при определении столбцов таблицы или впоследствии).

SET DEFAULТ устанавливает значения по умолчанию, подобно тому, как это делается в операторе CREATE DOMAIN.

DROP DEFAULТ отменяет текущие значения по умолчанию, назначенные домену.

[ADD [CONSTRAINT] CHECK (<огранич_домена>)] добавляет условия, которым должны соответствовать значения столбца, ассоциированного с доменом. При этом возможно определение условий, рассмотренных выше для предложения CHECK оператора CREATE DOMAIN.

DROP CONSTRAINT удаляет условия, определенные для домена в предложении CHECK оператора CREATE DOMAIN или предыдущих операторов ALTER DOMAIN.

Например, пусть определен домен ID_TYPE

CREATE DOMAIN ID_TYPE AS INTEGER CHECK(VALUE >= 100);

и в дальнейшем он использован при создании таблицы ААА:

CREATE TABLE ААА( ID ID_TYPE NOT NULL, FIO VARCHAR(20), PRIMARY KEY(ID));

Изменить условие, определяемое CHECK так, чтобы значение было больше или равно 100 и меньше или равно 500, можно за два такта. Сначала нужно удалить старое условие:

ALTER DOMAIN ID_TYPE DROP CONSTRAINT;

после чего добавить новое (которое на самом деле есть модифицированное старое):

ALTER DOMAIN ID_TYPE CHECK (VALUE >= 100 AND VALUE <= 500);

Заметим, что изменять определение таблицы ААА нет необходимости, и отныне в столбец ID этой таблицы можно занести значения, большие или равные 100 и меньшие или равные 500.