sql >> Base de Datos >  >> RDS >> PostgreSQL

Desencadenar para eliminar filas de tablas relacionadas antes de eliminar filas de la tabla real

Algunos consejos más sobre su función de activación:

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;

Puntos principales

  • Tu cheque de existencia con un SELECT estado de cuenta duplica el costo. Simplemente ejecute DELETE , si no se encuentra ninguna fila coincidente, no se elimina nada.

  • Usa un CASE declaración aquí. Más corto, más rápido. Tenga en cuenta que plpgsql CASE es ligeramente diferente de SQL CASE declaración. Por ejemplo, puede enumerar varios casos a la vez.

  • No necesitas el DECLARE palabra clave, a menos que realmente declare variables.

Diseño alternativo

Podría evitar el problema por completo mediante eliminaciones en cascada a través de clave externa , como @a_horse mencionado en el comentario . El diseño de mi esquema se vería así:

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

...

Acerca de serial :
Función SQL de incremento automático