Скачиваний:
124
Добавлен:
02.05.2014
Размер:
2.3 Mб
Скачать

8.9. Средства языка sql

Классификация ограничений целостности в языке SQL довольно сильно отличается от схемы, описанной в разделах 8.1-8.5. В языке SQL все ограничения делятся на три категории:

  • ограничения домена;

  • ограничения базовой таблицы;

  • общие ограничения (иначе называемые утверждениями).

Однако ограничения домена— это не то же самое, что обсуждавшиеся выше огра­ничения типа, а ограничения базовой таблицы отличаются от обсуждавшихся здесь ог­раничений переменной-отношения. Аналогично утверждения отличаются от понятия ограничений базы данных. Укажем некоторые особенности, касающиеся упомянутых понятий языка SQL.

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

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

  • Ограничения базовой таблицы и утверждения языка SQL (которые фактически взаимозаменяемы) упрощенно можно считать равносильными нашим ограничени­ям переменной-отношения и базы данных, вместе взятым.

Также отметим, что в языке SQL совершенно отсутствует поддержка ограничений перехода. В настоящее время не поддерживаются и триггерные процедуры, хотя их под­держка уже включена в новый стандарт SQL3 (см. приложение Б).

Ограничения домена

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

CREATE DOMAIN COLOR CHAR(6) DEFAULT '???' CONSTRAINT VALID_C0L0RS CHECK ( VALUE IN

{ 'Red', 'Yellow', 'Blue', 'Green', '???' ) ) ;

Предположим, что оператор CREATE TABLE для базовой таблицы Р (таблицы деталей) выглядит следующим образом.

CREATE TABLE Р { ... , COLOR COLOR, ... ) ;

Если пользователь вставляет в таблицу Р только часть новой строки, не содержащую значение для столбца COLOR, то по умолчанию в этот столбец будет помещено значение '???'. Если же пользователь укажет значение для столбца COLOR, но это значение не будет принадлежать диапазону допустимых для него значений, то операция не будет вы­полнена и система выдаст сообщение, в котором будет указано о нарушении пользовате­лем ограничения VALID_COLORS.

Как было показано в разделе 8.2, концептуально ограничения домена являются (или, ско­рее, должны являться) ничем иным, как перечнем значений, которые составляют этот домен, и приведенный выше пример ограничения VALID_C0L0RS, конечно, следует этому определе­нию. Однако в общем случае язык SQL позволяет включать в определение ограничений до­менов логические выражения произвольной сложности. Это предоставляет возможность ука­зывать, например, что допустимые значения некоторого домена D могут зависеть от значений указанного атрибута, присутствующих в настоящий момент в некоторой таблице Т. Читатель может поразмышлять о возможных последствиях такой неоправданной вседозволенности.

Ограничения базовой таблицы

В языке SQL существуют следующие виды ограничений базовой таблицы:

  • определение потенциального ключа;

  • определение внешнего ключа;

  • определение "проверочного условия".

Ниже каждое из них обсуждается подробнее.

Замечание. В языке SQL каждому определению ограничений может предшествовать предложение вида CONSTRAINT <имя ограничение, задающее имя нового ограничения (это замечание верно и для ограничений доменов, как мы уже убедились на примере ограничения VALID_COLORS). В приводимых ниже примерах мы будем игнорировать эту возможность.

Потенциальные ключи

Определение потенциального ключа записывается в следующем виде. UNIQUE ( <список имен столбцов> }

Возможна и другая форма записи. PRIMARY KEY ( <список имен столбцов> )

В обоих случаях параметр <список имен столбцов> не должен быть пустым. Для за­данной базовой таблицы может существовать не более одной спецификации PRIMARY KEY (первичный ключ) и любое количество спецификаций UNIQUE (альтернативные ключи). В случае первичного ключа для каждого из указанных столбцов дополнительно подразуме­вается наличие в определении спецификации NOT NULL, даже если эта спецификация не была указана явно. Проверка выполнения ограничений будет обсуждаться ниже.

Внешние ключи

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

FOREIGN KEY ( <список имен столбцов> )

REFERENCES <имя базовой таблицы> [ ( <список имен столбцов> ) ] [ ON DELETE <ссылочная операция> ] [ ON UPDATE <ссылочная операция> ]

Здесь параметр <ссылочная операция> может принимать значения NO ACTION (по умолчанию), CASCADE, SET DEFAULT и SET NULL. Опции SET DEFAULT и SET NULL будут рассматриваться в главе 18. Второй параметр <список имен столбцов> необходим в том случае, если внешний ключ ссылается на потенциальный ключ, который не является пер­вичным ключом.

Замечание. Соответствие "внешний ключ — потенциальный ключ" устанавлива­ется не на основе имен столбцов, а на основе позиции (слева направо) в списках имен атрибутов.

Проверочные условия

Определение проверочного условия (проверочного ограничения) имеет следующий вид. CHECK ( <условное выражение> )

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

Замечание. Условное выражение в языке SQL является аналогом того, что ранее мы называли логическим (или булевым) выражением. Эти выражения подробно рассматри­ваются в приложении А. В частности, отметим, что в данном контексте условное выра­жение может быть сколь угодно сложным. Не требуется, чтобы условие ограничения включало ссылки только на таблицу Т; оно может иметь ссылки на что угодно в базе данных. Читателю, опять-таки, будет полезно поразмышлять над тем, какими могут быть последствия такой неоправданной вседозволенности.

Вот пример создания таблицы с помощью оператора CREATE TABLE, в котором ис­пользуются ограничения базовой таблицы всех трех типов.

CREATE TABLE SP

( St St NOT NULL, Pi Pi NOT NULL, QTY QTY NOT NULL, PRIMARY KEY ( St, Pi ), FOREIGN KEY ( St ) REFERENCES S

ON DELETE CASCADE

ON UPDATE CASCADE, FOREIGN KEY ( Pi ) REFERENCES P

ON DELETE CASCADE

ON UPDATE CASCADE, CHECK ( QTY > 0 AND QTY < 5001 ) ) ;

Здесь подразумевается, что домены Si, Pi и QTY уже определены, а атрибуты Si и Р| явно определены как первичные ключи для таблиц S и Р соответственно. Также здесь умышленно применяется соглашение по сокращению, благодаря которому проверочное условие вида

CHECK ( <имя стол6ца> IS NOT NULL )

в определении рассматриваемого столбца можно заменить простой спецификацией NOT NULL. В соответствии с данным правилом в этом примере три достаточно громозд­ких проверочных условия заменены тремя простейшими спецификациями NOT NULL.

Завершая подраздел, обратим внимание на некоторую "странность": считается, что ограничение базовой таблицы SQL всегда удовлетворено, если базовая таблица пуста, причем даже в случае ограничения вида "эта таблица не должна быть пустой"!

Утверждения

Рассмотрим третий случай: общие ограничения, иначе называемые утверждениями. Общие ограничения создаются с помощью оператора CREATE ASSERTION, имеющего следующий синтаксис.

CREATE ASSERTION <имя ограничение CHECK ( <условное выражение> ) ;

Здесь параметр <имя ограничение задает имя создаваемого ограничения, а параметр <условное выражение> определяет проверяемое условное выражение. Для отмены обще­го ограничения используется оператор DROP ASSERTION.

DROP ASSERTION <имя ограничение ;

Отметим, что в отличие от всех других форм SQL-оператора отмены DROP, приведен­ных в этой книге (DROP DOMAIN, DROP TABLE, DROP VIEW), оператор DROP ASSERTION не содержит опций RESTRICT и CASCADE.

Вот несколько примеров утверждений, создаваемых с помощью оператора CREATE ASSERTION.

1. Каждый поставщик должен иметь статус не менее 5.

CREATE ASSERTION IC13 CHECK

( ( SELECT MIN ( S.STATUS ) FROM S ) > 4 ) ;

2. Значение веса любой детали должно быть положительным.

CREATE ASSERTION IC18 CHECK

{ NOT EXISTS ( SELECT * FROM P

WHERE NOT ( P.WEIGHT > 0 ) ) ) ;

3. Все красные детали должны храниться в Лондоне.

CREATE ASSERTION IC99 CHECK

( NOT EXISTS ( SELECT * FROM P

WHERE P.COLOR = 'Red'

AND P.CITY <> 'London' ) ) ;

4. He допускаются поставки с общим весом (произведение количества деталей и их веса), превышающим 20 ООО фунтов.

CREATE ASSERTION IC46 CHECK

( NOT EXISTS ( SELECT * FROM P, SP WHERE P.P# = SP.Pi

AND ( P.WEIGHT * SP.QTY ) > 20000.0 ) ) ;

5. Поставщики со статусом, меньшим 20, не имеют права поставлять любую деталь в количестве более 500 штук.

CREATE ASSERTION IC95 CHECK

( NOT EXISTS ( SELECT * FROM S, SP WHERE S.STATUS < 20 AND S.Sf = SP.SI AND SP.QTY > 500 ) ) ;

Откладываемая проверка

Классификация ограничений целостности в языке SQL отличается от нашей также в отношении вопроса, когда должна выполняться проверка. В нашей схеме ограничения базы данных проверяются во время выполнения оператора COMMIT, а остальные ограни­чения проверяются немедленно. В языке SQL подход иной и ограничения могут быть определены как откладываемые и неоткладываемые (опции DEFERRABLE и NOT DEFERRABLE соответственно). Если ограничение откладываемое, оно дополнительно мо­жет быть определено как исходно откладываемое (INITIALLY DEFERRED) или исходно выполняемое (INITIALLY IMMEDIATE), что определяет состояние ограничения в начале выполнения каждой транзакции. Неоткладываемые ограничения всегда проверяются не­медленно, а откладываемые могут динамически включаться и отключаться с помощью оператора, синтаксис которого приведен ниже.

SET CONSTRAINTS <список имен ограничений> <параметр> ;

Здесь параметр <параметр> — это или ключевое слово IMMEDIATE (немедленно), или ключевое слово DEFERRED (отложено). Примером может служить следующее утверждение.

SET CONSTRAINTS IC46, IC95 DEFERRED ;

Откладываемые ограничения проверяются только тогда, когда они находятся в со­стоянии IMMEDIATE (немедленно). Установка откладываемого ограничения в состояние IMMEDIATE, естественно, приводит к тому, что оно проверяется немедленно. Если про­верка завершается ошибкой, то завершается ошибкой и оператор SET IMMEDIATE. При выполнении операции завершения транзакции (COMMIT) все откладываемые ограничения целостности переходят в выполняемое состояние IMMEDIATE и если какая-либо проверка завершается ошибкой, выполняется откат транзакции.

Соседние файлы в папке Дейт К. Дж. Введение в системы баз данных [7 издание]