2017-01-20 2 views
0

In meinem Postgres 9.4 Datenbank, ich habe die folgenden Trigger/Funktion, die eine "Soft-löscht" Funktionalität implementiert:Wie implementiert man ein Löschen von gelöschten Datensätzen in Postgres?

ALTER TABLE my_schema.my_table 
ADD COLUMN delete_ind integer 


CREATE OR REPLACE FUNCTION trigger_mytable_soft_delete() 
    RETURNS trigger AS $$ 
    DECLARE 
     command text := ' SET delete_ind = 1 WHERE uuid_col = $1'; 
    BEGIN 
     EXECUTE 'UPDATE "my_schema"."my_table"' || TG_TABLE_NAME || command USING OLD.uuid_col; 
     RETURN NULL; 
    END; 
    $$ LANGUAGE plpgsql; 


CREATE TRIGGER my_table_soft_delete_trigger 
    BEFORE DELETE ON "my_schema"."my_table" 
    FOR EACH ROW EXECUTE PROCEDURE trigger_mytable_soft_delete(); 

Der Code gibt mir über die "soft-löscht" Funktionalität, sondern auch hindert mich daran, die Zeilen, die bereits als gelöscht markiert sind, zu löschen/zu löschen.

Das neue gewünschte Verhalten ist, diese Löschfunktion zu haben, um den Wert des delete_ind-Felds zu prüfen, und, wenn es bereits auf 1 gesetzt ist, diese Zeile endgültig zu löschen.

Was ist die richtige bedingte Syntax, die den Wert von delete_ind setzen würde. oder löschen Sie die fragliche Zeile tatsächlich basierend auf dem aktuellen Wert der Spalte delete_ind?

Antwort

2

Es kann mit einer relativ geringen Änderung Ihrer Funktion erfolgen:

CREATE OR REPLACE FUNCTION trigger_mytable_soft_delete() 
RETURNS trigger AS 
$$ 
BEGIN 
    if OLD.delete_ind = 1 then 
     /* Delete proceeds, you just needs to *do nothing* 
      except for returning the OLD row as it were */ 
     RETURN OLD ; 
    else 
     /* instead of deleting, set a flag */ 
     UPDATE my_schema.my_table 
      SET deleted_ind = 1 
     WHERE uuid_col = old.uuid_col ; 

     /* This will skip the process of this row. 
      It will also avoid subsequent triggers to be fired, and the row will 
      not be counted on the rows-affected count. If more triggers need 
      to be processed, make sure this is the last in the chain. 
     */ 
     RETURN NULL ; 
    end if ; 
END; 
$$ 
LANGUAGE plpgsql; 

(Wenn Ihre Funktion verwendet wird, eins nach dem anderen Tisch, können Sie es hart Code, und müssen nicht dynamische SQL)


Exkurs: Wenn die Spalte delete_ind nur als Flagge, seine Bedeutung, indem sie es als boolean not null erklärt befördert würde am besten verwendet werden anstelle von integer.

Verwandte Themen