Вложенные запросы в проверочных ограничениях |
||
Мы уже многое сделали, чтобы наша реляционная модель соответствовала предметной области. Однако некоторые проблемы, нарушающие согласованность данных, остались. Например, мы можем добавить в таблицу PC модель (1288), которая в таблице Product объявлена как принтер:
Более того, ничто не мешает нам добавить эту модель во все продукционные таблицы – PC, Laptop, Printer. Итак, нам требуется ограничение, которое бы запретило иметь в подчиненных таблицах продукты несоответствующего типа. Сформулируем проверочное ограничение, которое будет определять тип модели по таблице Product и сравнивать его с типом продукционной таблицы. Например, для таблицы PC такое ограничение могло бы иметь вид:
При попытке выполнить вышеприведенный код (вполне легитимный с точки зрения стандарта SQL-92) получаем сообщение об ошибке: Subqueries are not allowed in this context. Only scalar expressions are allowed. (Вложенные запросы в данном контексте запрещены. Допускаются только скалярные выражения.) Другими словами, Cистема управления реляционными базами данных (СУБД), разработанная корпорацией Microsoft. Язык структурированных запросов) — универсальный компьютерный язык, применяемый для создания, модификации и управления данными в реляционных базах данных. SQL Server не допускает использования подзапросов в ограничении CHECK. Что касается реализаций, то это, кстати, больше правило, чем исключение. Что касается MySQL, то эта СУБД вообще не поддерживает ограничений CHECK. Восполнить этот пробел в SQL Server позволяет использование функций пользователя (UDF). Трюк состоит в следующем. Поскольку, как это следует из сообщения об ошибке, в ограничении CHECK допускаются лишь скалярные выражения, напишем скалярнозначную функцию, которая будет принимать номер модели и возвращать ее тип, указанный в таблице Product. Затем эту функцию мы будем использовать в ограничении. Итак,
Теперь добавим ограничение:
Теперь при попытке вставить в таблицу PC модель принтера, например:
The INSERT statement conflicted with the CHECK constraint "model_type". The conflict occurred in database "learn", table "dbo.pc", column 'model'. (Конфликт инструкции INSERT с ограничением CHECK "model_type". Конфликт произошел в базе данных "learn", таблица "dbo.pc", столбец 'model'. Выполнение данной инструкции было прервано.) Модель же соответствующего типа можно добавить в таблицу:
Надеюсь, что вам не составит труда написать подобные ограничения и для остальных таблиц этой схемы. |