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 umSELECT
declaração dobra o custo. Basta executar oDELETE
, se nenhuma linha correspondente for encontrada, nada será excluído.
-
Use umCASE
declaração aqui. Mais curto, mais rápido. Observe que plpgsqlCASE
é um pouco diferente do SQLCASE
declaração. Por exemplo, você pode listar vários casos ao mesmo tempo.
-
Você não precisa doDECLARE
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