При создании сложных структур базы данных, включающих множество таблиц с ограничениями внешних ключей, представлениями, триггерами, функциями и т. д., вы неявно создаете сеть зависимостей между объектами. Например, таблица с ограничением внешнего ключа зависит от таблицы, на которую она ссылается.
Для обеспечения целостности всей структуры базы данных, Digital Q.DataBase гарантирует, что вы не сможете удалить объекты, от которых все еще зависят другие объекты. Например, попытка удалить таблицу products, которую мы рассматривали в Раздел 2.2.5.5, при наличии зависящей от нее таблицы orders, приведет к появлению сообщения об ошибке следующего вида:
DROP TABLE products; ERROR: cannot drop table products because other objects depend on it DETAIL: constraint orders_product_no_fkey on table orders depends on table products HINT: Use DROP ... ключевое слово CASCADE, чтобы также удалить зависимые объекты.
Сообщение об ошибке содержит полезную подсказку: если нет необходимости удалять все зависимые объекты по отдельности, можно выполнить команду:
DROP TABLE products CASCADE;
в этом случае все зависимые объекты будут удалены, как и любые объекты, которые зависят от них, рекурсивно. В данном случае таблица orders не удаляется; удаляется только ограничение внешнего ключа. На этом выполнение прекращается, так как от данного ограничения внешнего ключа ничего не зависит. (Если вы хотите проверить, что DROP ... CASCADE выполнит,
запустите DROP без CASCADE и прочтите
DETAIL в выводе.)
Почти все DROP команды в Digital Q.DataBase поддерживают
указание CASCADE. Разумеется, характер возможных зависимостей варьируется в зависимости от типа объекта. Также можно указать RESTRICT вместо
CASCADE для обеспечения стандартного поведения, которое заключается в запрете удаления объектов, имеющих зависимые объекты.
Согласно стандарту SQL, указание одного из
RESTRICT или CASCADE является
обязательным в DROP команды. Фактически ни одна система баз данных не контролирует соблюдение этого правила, однако поведение по умолчанию RESTRICT или CASCADE различается
в зависимости от системы.
Если DROP команда перечисляет несколько
объектов, CASCADE требуется только при наличии зависимостей вне указанной группы. Например, в команде
DROP TABLE tab1, tab2 наличие внешнего ключа, ссылающегося из tab1 из на не будет означать, что CASCADE необходимо для успешного выполнения.
Для определяемой пользователем функции или процедуры, тело которой определено в виде строкового литерала, Digital Q.DataBase отслеживает зависимости, связанные с внешне видимыми свойствами функции, такими как типы её аргументов и результата, но а не зависимости, которые могут быть выявлены только путем анализа тела функции. В качестве примера рассмотрим следующую ситуацию:
CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow',
'green', 'blue', 'purple');
CREATE TABLE my_colors (color rainbow, note text);
CREATE FUNCTION get_color_note (rainbow) RETURNS text AS
'SELECT note FROM my_colors WHERE color = $1'
LANGUAGE SQL;
(См. Раздел 5.1.5 для получения пояснений о функциях на языке SQL.) Digital Q.DataBase будет учитывать, что get_color_note функция зависит от rainbow
: удаление типа приведет к принудительному удалению функции, поскольку тип её аргумента больше не будет определен. Однако Digital Q.DataBase
не будет считать, get_color_note зависеть от my_colors таблицы, и поэтому не удалит функцию при удалении таблицы. Хотя у этого подхода есть недостатки,
он также обладает преимуществами. В некотором смысле функция остается корректной, даже если таблица отсутствует, хотя её выполнение приведет к ошибке; создание новой
таблицы с тем же именем позволит функции снова работать.
С другой стороны, для функции или процедуры на языке SQL, тело которой написано в соответствии со стандартом SQL, разбор тела происходит во время определения функции, и все распознанные парсером зависимости сохраняются. Таким образом, если определить вышеуказанную функцию следующим образом:
CREATE FUNCTION get_color_note (rainbow) RETURNS text BEGIN ATOMIC SELECT note FROM my_colors WHERE color = $1; END;
тогда зависимость функции от my_colors
таблицы будет известна и обеспечена системой DROP.