Существует три основных способа решения этой проблемы, поскольку ограничения CHECK не могут быть основаны на запросе.
Вариант 1: Триггеры
Самый упрощенный подходбыло бы поставить триггер на TANK, который запрашивает TANKS и выдает исключение, если УРОВЕНЬ превышает CAPACITY.Однако проблема такого упрощенного подхода заключается в том, что практически невозможно правильно обрабатывать проблемы параллелизма.Если сеанс 1 уменьшает CAPACITY, тогда сеанс 2 увеличивает УРОВЕНЬ, и затем обе транзакции фиксируются, триггеры не смогут обнаружить нарушение.Это может не быть проблемой, если одна или обе таблицы редко модифицируются, но в целом это будет проблемой.
Вариант 2: Материализованные представления
Вы можете решить проблему параллелизма, создав материализованное представление ON COMMIT, которое присоединяется к таблице TANK и TANKS, а затем создав ограничение CHECK для материализованного представления, которое подтверждает, что LEVEL <= CAPACITY.Вы также можете избежать двойного хранения данных, так как материализованное представление содержит только данные, которые нарушают ограничение.Это потребует материализованных журналов представлений в обеих базовых таблицах, что добавит немного накладных расходов на вставки (хотя и меньше, чем при использовании триггеров).Подтверждение проверки для фиксации времени решит проблему параллелизма, но она представляет небольшую проблему управления исключениями, поскольку операция COMMIT теперь может завершиться ошибкой, поскольку не удалось обновить материализованное представление.Ваше приложение должно быть в состоянии справиться с этой проблемой и предупредить пользователя об этом факте. </p>
Вариант 3: Изменить модель данных
Если у вас есть значениев таблице A, которая зависит от предела в таблице B, это может указывать на то, что предел в B должен быть атрибутом таблицы A (вместо или в дополнение к атрибуту таблицы B).Конечно, это зависит от специфики вашей модели данных, но это часто стоит учитывать.