суббота, 9 июля 2022 г.

Какого ограничения целостности не хватает в SQL

Константного - когда значение в столбце, присвоенное insert'ом, нельзя изменить update'ом.

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

Можно, конечно, создать триггер для update, который запретит изменение, если новое значение такого столбца отличается от старого.

Но куда изящнее было бы запретить изменение декларативно:

-- значение art_type не может изменяться после создания записи
alter table article add constant (art_type);

Поискал что-то подобное в книгах.

В небезызвестном "Введении в системы баз данных" К. Дж. Дейта, 8-е издание, в Главе 9 "Целостность данных" прочитал:

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

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

-- значение art_type константное, не изменяется при обновлениях
alter table article add check (not updating or old.art_type = new.art_type);

-- значение modcount при обновлениях всегда возрастает на 1
alter table article add check (not updating or old.modcount + 1 = new.modcount);

Здесь updating работает как в триггерах СУБД Oracle и оказывается true при выполнении операции update и false при выполнении insert и delete (для которых есть аналогичные проверки inserting и deleting).

Комментариев нет:

Отправить комментарий