PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Acionador para excluir linhas de tabelas relacionadas antes de excluir linhas da tabela real


Mais alguns conselhos sobre sua função de gatilho:
CREATE OR REPLACE FUNCTION delete_question()
  RETURNS trigger AS
$func$
BEGIN

CASE OLD.que_type
WHEN 1 THEN
    DELETE FROM mcq   WHERE que_id=OLD.id;
WHEN 2, 3 THEN
    DELETE FROM tffb  WHERE que_id=OLD.id;
WHEN 4 THEN
    DELETE FROM essay WHERE que_id=OLD.id;
-- ELSE
--      Do something?
END CASE;

RETURN OLD;

END
$func$ LANGUAGE plpgsql;

Pontos principais


  • Sua verificação de existência com um SELECT declaração dobra o custo. Basta executar o DELETE , se nenhuma linha correspondente for encontrada, nada será excluído.

  • Use um CASE declaração aqui. Mais curto, mais rápido. Observe que plpgsql CASE é um pouco diferente do SQL CASE declaração. Por exemplo, você pode listar vários casos ao mesmo tempo.

  • Você não precisa do DECLARE palavra-chave, a menos que você realmente declare variáveis.

Design alternativo


Você pode evitar o problema completamente exclusões em cascata via chave estrangeira , como @a_horse mencionado no comentário . Meu layout de esquema ficaria assim:
CREATE TABLE question (
   question_id serial NOT NULL PRIMARY KEY
  ,que_type    int   -- this may be redundant as well
);

CREATE TABLE essay (
   que_id int NOT NULL PRIMARY KEY
              REFERNECES question(question_id) ON UPDATE CASCADE
                                               ON DELETE CASCADE
  ,ans    text
);

...

Sobre serial :
Função SQL de incremento automático