Quando é criada uma estrutura de banco de dados complexa, envolvendo muitas tabelas com restrições de chave estrangeira, visões, gatilhos, funções, etc., é criada implicitamente uma rede de dependências entre os objetos. Por exemplo, uma tabela com uma restrição de chave estrangeira depende da tabela à qual faz referência.
Para garantir a integridade de toda a estrutura do banco de dados, o PostgreSQL não permite excluir um objeto quando há outros objetos dependentes dele. Por exemplo, tentar excluir a tabela de produtos declarada na Seção 5.5.5, onde a tabela de pedidos depende dela, produz a seguinte mensagem de erro:
DROP TABLE produtos;
ERRO: não é possível remover tabela produtos, porque outros objetos dependem dela
DETALHE: restrição pedidos_num_produto_fkey na tabela pedidos depende da tabela produtos
DICA: Use DROP ... CASCADE para remover os objetos dependentes também.
A mensagem de erro contém uma dica útil: se não quiser se preocupar com a exclusão de todos os objetos dependentes individualmente, então você poderá executar
DROP TABLE produtos CASCADE;
NOTA: removendo em cascata a restrição pedidos_num_produto_fkey na tabela pedidos
DROP TABLE
e todos os objetos dependentes serão removidos, assim como quaisquer
objetos que dependam deles também, recursivamente.
Neste caso, o comando não remove a tabela de pedidos, apenas remove a
restrição de chave estrangeira.
O comando termina por aí, porque nada mais depende da restrição de
chave estrangeira. (Se quiser verificar o que
DROP ... CASCADE vai fazer, então execute
DROP sem CASCADE e leia a linha
DETALHE da mensagem de erro)
Quase todos os comandos DROP no
PostgreSQL permitem especificar
CASCADE. Obviamente, a natureza das possíveis
dependências varia conforme o tipo do objeto. Também pode ser escrito
RESTRICT em vez de CASCADE
para obter o comportamento padrão, que é evitar a exclusão de
objetos dos quais quaisquer outros objetos dependem.
Segundo o padrão SQL, é necessário
especificar RESTRICT ou CASCADE
em um comando DROP. Na realidade, nenhum sistema
de banco de dados impõe esta regra, mas se o comportamento padrão é
RESTRICT ou CASCADE varia
entre os sistemas.
Se o comando DROP incluir vários objetos,
só será necessário usar CASCADE quando houver
dependências fora do grupo especificado. Por exemplo, ao se escrever
DROP TABLE tab1, tab2, a existência de uma chave
estrangeira referenciando tab1 oriunda de
tab2 não significa que CASCADE
seja necessário para obter sucesso.
Para funções ou procedimentos definidos pelo usuário cujo corpo é definido como uma cadeia de caracteres, o PostgreSQL rastreia as dependências associadas às propriedades da função visíveis externamente, como seus tipos de dados de argumentos e resultados, mas não as dependências que só podem ser conhecidas examinando o corpo da função. Como exemplo, considere a seguinte situação:
CREATE TYPE arco_iris AS ENUM ('vermelho', 'laranja', 'amarelo',
'verde', 'azul', 'anil', 'violeta');
CREATE TABLE minhas_cores (cor arco_iris, nota text);
CREATE FUNCTION obter_nota_pela_cor (arco_iris) RETURNS text AS
'SELECT nota FROM minhas_cores WHERE cor = $1'
LANGUAGE SQL;
(Veja a Seção 36.5 para obter uma explicação das
funções da linguagem SQL.)
O PostgreSQL saberá que a função
obter_nota_pela_cor depende do tipo de dados
arco_iris: excluir o tipo de dados forçaria a exclusão
da função, porque o tipo de dados de seu argumento não estaria mais
definido.
Mas o PostgreSQL não vai considerar
obter_nota_pela_cor como dependente da tabela
minhas_cores, portanto não vai excluir a
função se a tabela for excluída.
Embora haja desvantagens nessa abordagem, também há benefícios.
A função ainda é válida em algum sentido se a tabela estiver ausente,
embora executá-la cause um erro; criar uma nova tabela com o mesmo
nome permitiria que a função voltasse a funcionar novamente.