PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Déclencheur pour supprimer les lignes des tables associées avant de supprimer les lignes de la table réelle

Quelques conseils supplémentaires sur votre fonction de déclenchement :

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;

Points majeurs

  • Votre contrôle d'existence avec un SELECT déclaration double le coût. Exécutez simplement le DELETE , si aucune ligne correspondante n'est trouvée, rien n'est supprimé.

  • Utiliser un CASE déclaration ici. Plus court, plus rapide. Notez que plpgsql CASE est légèrement différent de SQL CASE déclaration. Par exemple, vous pouvez répertorier plusieurs cas à la fois.

  • Vous n'avez pas besoin de DECLARE mot-clé, sauf si vous déclarez réellement des variables.

Conception alternative

Vous pouvez éviter complètement le problème en suppressions en cascade par clé étrangère , comme @a_horse mentionné dans le commentaire . La mise en page de mon schéma ressemblerait à ceci :

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
);

...

À propos de serial :
Fonction SQL d'incrémentation automatique