Pergunta

É possível evitar a exclusão da primeira linha na tabela no lado PostgreSQL?

Eu tenho uma tabela categoria e quero evitar a exclusão de categoria padrão como poderia quebrar a aplicação. Claro que eu poderia facilmente fazê-lo no código do aplicativo, mas seria muito melhor fazê-lo no banco de dados.

Eu acho que tem algo a ver com as regras de instrução de exclusão, mas eu não poderia encontrar qualquer coisa remotamente perto do meu problema na documentação.

Foi útil?

Solução

A melhor maneira que eu vejo de conseguir isso é através da criação de um disparador de exclusão nesta tabela. Basicamente, você tem que escrever um procedimento armazenado para se certificar de que esta categoria 'default' sempre vai existir, e depois aplicá-la usando um disparador ON evento delete nesta tabela. Uma boa maneira de fazer isso é criar um gatilho per-linha que vai garantir que em eventos excluir a linha de categoria 'default' nunca serão apagados.

Por favor, verifique a documentação do PostgreSQL sobre gatilhos e procedimentos armazenados:

http://www.postgresql.org/docs/8.3 /interactive/trigger-definition.html

http://www.postgresql.org/docs/8.3/interactive /plpgsql.html

Há também exemplos valiosos neste wiki:

http://wiki.postgresql.org/wiki/A_Brief_Real-world_Trigger_Example

Outras dicas

Você estava certo sobre o pensamento do sistema de regras. Aqui é um link para um exemplo combinando o seu problema. É ainda mais simples do que os gatilhos:

create rule protect_first_entry_update as
  on update to your_table
  where old.id = your_id
  do instead nothing;
create rule protect_first_entry_delete as
  on delete to your_table
  where old.id = your_id
  do instead nothing;

Algumas respostas perca um ponto: também a atualização da linha protegida tem de ser restrito. Caso contrário, pode-se primeiro atualizar a linha protegida de modo a que deixe de preencher o critério de exclusão proibido, e, em seguida, pode-se excluir a linha atualizada, uma vez que não está mais protegida.

Você quer definir um antes de excluir- gatilho sobre a mesa. Quando você tenta excluir a linha (ou jogo de PK ou ter um separado "proteger" boolean coluna), AUMENTO uma exceção.

Eu não estou familiarizado com a sintaxe do PostgreSQL, mas parece que é assim que você faria isso:

CREATE FUNCTION check_del_cat() RETURNS trigger AS $check_del_cat$
    BEGIN            
        IF OLD.ID = 1 /*substitute primary key value for your row*/ THEN
            RAISE EXCEPTION 'cannot delete default category';
        END IF;

    END;
$check_del_cat$ LANGUAGE plpgsql;

CREATE TRIGGER check_del_cat BEFORE DELETE ON categories /*table name*/
    FOR EACH ROW EXECUTE PROCEDURE check_del_cat();

Você poderia ter uma linha em outra tabela (chamados padrões) referenciando a categoria padrão. A restrição FK não deixaria a exclusão da categoria padrão acontecer.

Tenha em mente como gatilhos trabalhar. Eles vão disparar para cada linha sua instrução de exclusão excluirá. Isso não significa que você não deve usar triggers apenas manter isso em mente e, mais importante testar os seus cenários de uso e certifique-se o desempenho satisfaz os requisitos.

Devo usar uma regra ou um gatilho?

De docs oficiais: "Para as coisas que podem ser implementadas por ambos, o que é melhor depende da utilização do banco de dados. O gatilho é disparado para qualquer linha afetada uma vez. A regra manipula a consulta ou gera uma consulta adicional. Portanto, se muitas linhas são afetadas de uma instrução, uma regra de emissão de um comando extra é provável que seja mais rápido do que um gatilho que é chamado para cada linha e deve executar suas operações muitas vezes. no entanto, a abordagem gatilho é conceitualmente muito mais simples do que a abordagem regra, e é mais fácil para novatos para obter direito. "

Veja a documentação para mais detalhes.
http://www.postgresql.org/docs/8.3/interactive/ regras-triggers.html

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top