PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Trigger zum Löschen von Zeilen aus verknüpften Tabellen, bevor Zeilen aus der tatsächlichen Tabelle gelöscht werden

Noch ein paar Ratschläge zu deiner Trigger-Funktion:

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;

Wichtige Punkte

  • Ihre Existenzprüfung mit einem SELECT Aussage verdoppelt die Kosten. Führen Sie einfach DELETE aus , wenn keine übereinstimmende Zeile gefunden wird, wird nichts gelöscht.

  • Verwenden Sie einen CASE Aussage hier. Kürzer, schneller. Beachten Sie, dass plpgsql CASE unterscheidet sich geringfügig von SQL CASE Aussage. Sie können beispielsweise mehrere Fälle auf einmal auflisten.

  • Sie brauchen das DECLARE nicht Schlüsselwort, es sei denn, Sie deklarieren tatsächlich Variablen.

Alternatives Design

Sie könnten das Problem vollständig vermeiden, indem Sie Löschungen kaskadieren über Fremdschlüssel , als @a_horse im Kommentar erwähnt . Mein Schema-Layout würde so aussehen:

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

...

Über serial :
SQL-Funktion automatisch inkrementieren