Категории
Самые читаемые
PochitayKnigi » Компьютеры и Интернет » Программирование » Firebird РУКОВОДСТВО РАЗРАБОТЧИКА БАЗ ДАННЫХ - Хелен Борри

Firebird РУКОВОДСТВО РАЗРАБОТЧИКА БАЗ ДАННЫХ - Хелен Борри

Читать онлайн Firebird РУКОВОДСТВО РАЗРАБОТЧИКА БАЗ ДАННЫХ - Хелен Борри

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 43 44 45 46 47 48 49 50 51 ... 238
Перейти на страницу:

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

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].

Атрибут CHARSET/CHARACTER SET

Для систем, которым нужно множество наборов символов внутри одной базы данных, объявление доменов, связанных с наборами символов для всех ваших символьных столбцов (CHAR, VARCHAR SUB_TYPE 1 и массивов символьных типов), может быть очень элегантным способом работы. Синтаксис определения набора символов можно посмотреть в предыдущей главе.

Атрибут COLLATE

Предложение COLLATE в операторе создания домена задает явную последовательность сортировки для доменов CHAR и VARCHAR. Вы должны выбрать порядок сортировки, который поддерживается набором символов, объявленным наследуемыми и предполагаемым для домена.

Синтаксис определения COLLATE см. в главе 11. Список последовательностей сортировки, доступных для каждого набора символов, см. в приложении 8.

Использование доменов в определении столбца

Пример

В некоторой базе данных есть домен SYSUSER, размером до 31 символа, имеющий значение по умолчанию, получаемое из контекстной переменной CURRENT_USER:

CREATE DOMAIN SYSUSER AS VARCHAR(31) DEFAULT CURRENT_USER;

Объявляемая таблица содержит столбец UPDATED_BY, который использует домен

SYSUSER:

CREATE TABLE LOANS (

LOAN_DATE DATE,

UPDATED_BY SYSUSER,

LOAN_FEE DECIMAL(15,2));

Клиент содержит оператор INSERT для таблицы LOANS:

INSERT INTO LOANS (LOAN_DATE, LOAN_FEE)

VALUES (116-MAY-20041, 10.75);

Поскольку этот оператор не содержит столбец UPDATED BY в списке столбцов, Firebird автоматически задает имя текущего пользователя ALICEFBIRD:

SELECT * FROM LOANS;

вернет

16-MAY-2004 ALICEFBIRD 10.75

! ! !

ПРИМЕЧАНИЕ. Здесь уместно напомнить, что значения по умолчанию для домена и столбца применяются только при добавлении и только если столбец, имеющий значение по умолчанию, отсутствует во входном списке оператора INSERT. Триггеры имеют более надежные способы реализации значений по умолчанию. Техники обсуждаются в главе 31.

. ! .

Переопределения в доменах

Столбцы, созданные с использованием доменов, могут переопределять некоторые наследуемые от домена атрибуты, заменяя наследуемый атрибут эквивалентным предложением атрибута. Определение столбца также может добавлять другие атрибуты. В табл. 13.1 описано, какие атрибуты могут, а какие не могут быть переопределены.

Таблица 13.1. Переопределение атрибутов доменов и столбцов

Атрибут

Переопределяется?

Замечания

Тип данных

Нет

DEFAULT

Да

CHARACTER SET

Да

Также может использоваться, чтобы восстановить для столбца значения по умолчанию базы данных

COLLATE

Да

CHECK

Нет

Используйте предложение CHECK в операторе CREATE или ALTER TABLE для добавления в проверку новых условий

NOT NULL

Нет

Атрибут NOT NULL на уровне домена не может быть переопределен на уровне столбца. Во многих случаях лучше оставить для домена возможность пустого значения и добавлять ограничение NOT NULL для столбцов, где это необходимо, в операторе CREATE или ALTER TABLE

Следующий оператор демонстрирует, как расширяется список атрибутов столбца, основанного на домене, созданного в одном из предыдущих примеров:

CREATE DOMAIN TEL_NUMBER

AS VARCHAR(18)

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

Скажем, мы хотим определить таблицу, содержащую столбец с номером телефона. Нам нужны атрибуты домена, но нам также необходимо обеспечить, чтобы нецифровые символы вводились в верхнем регистре:

CREATE TABLE LIBRARY_USER (

USER_ID INTEGER NOT NULL.

. . . <другие столбцы>,

PHONE_NO TEL_NUMBER,

CONSTRAINT CHK_TELNUM_UPPER

CHECK (PHONE_NO = UPPER(PHONE_NO))

);

Теперь у нас есть дополнительная проверка CHECK для этого столбца. Следующий оператор:

INSERT INTO LIBRARY_USER VALUES (USER_ID, PHONE_NO)

VALUES (99, '(09) 43889 wish');

будет ошибочным, потому что дополнительное ограничение CHECK требует, чтобы телефонный номер был '(09) 43889 wish'.

Когда домены не работают

Домен не может быть использован:

* в функции CAST (<имя_домена> AS <другой_тип>);

* вместо явного типа данных при определении входных и выходных аргументов хранимых процедур;

* при объявлении типа данных локальной переменной в триггере или хранимой процедуре;

* при определении типа данных элементов массива. При этом сам домен может быть массивом.

Объявление домена BOOLEAN

Firebird не поддерживает тип данных BOOLEAN. Домены в стиле BOOLEAN являются идеалом, потому что вы можете объявлять атрибуты, которые будут постоянными для всех таблиц. Рекомендуется использование минимальных типов данных: CHAR для переключателя T[rue]/F[aise] или Y[es]/N[о] или SMALLINT для пары 1/0. Следующие примеры предлагают способы, которыми вы можете реализовать ваши типы BOOLEAN.

Пример 13.1. Двухфазный переключатель со значением по умолчанию 'F' (False)

CREATE DOMAIN D_BOOLEAN AS CHAR

DEFAULT 'F' NOT NULL

CHECK(VALUE IN ('T', 'F'));

Пример 13.2. Трехфазный переключатель, допускающий значение UNKNOWN (т. е. NULL):

CREATE DOMAIN D_LOGICAL AS SMALLINT

CHECK(VALUE IS NULL OR VALUE IN (1,0));

Пример 13.3. Трехфазный переключатель, представляющий UNKNOWN как значение:

CREATE DOMAIN D_GENDER AS CHAR(4)

DEFAULT 'N/K' NOT NULL

1 ... 43 44 45 46 47 48 49 50 51 ... 238
Перейти на страницу:
Тут вы можете бесплатно читать книгу Firebird РУКОВОДСТВО РАЗРАБОТЧИКА БАЗ ДАННЫХ - Хелен Борри.
Комментарии