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

Trigger zum Einfügen von Zeilen in die entfernte Datenbank nach dem Löschen

Dies ist eine eingeschränkte Anwendung der Replikation. Die Anforderungen sind sehr unterschiedlich, daher gibt es eine Reihe verschiedener etablierter Lösungen für unterschiedliche Situationen. Beachten Sie die Übersicht im Handbuch.

Ihre handgestrickte, Trigger-basierte Lösung ist eine praktikable Option für relativ wenige Löschungen. Das Öffnen und Schließen einer separaten Verbindung für jede Zeile verursacht einen ziemlichen Overhead. Es gibt verschiedene andere Optionen.

Während Wenn ich mit dblink arbeite, schlage ich einige Modifikationen vor. Am wichtigsten:

  • Verwenden Sie format() um Zeichenketten eleganter zu entkommen.

  • Fahren Sie an der ganzen Reihe vorbei anstatt jede einzelne Spalte zu passieren und zu maskieren.

  • Platzieren Sie das Passwort nicht in jeder einzelnen Auslösefunktion.
    Verwenden Sie einen FOREIGN SERVER plus USER MAPPING . Detaillierte Anweisungen hier:

Grundsätzlich einmal ausführen auf dem Quellserver:

CREATE SERVER myserver FOREIGN DATA WRAPPER dblink_fdw
OPTIONS (hostaddr '127.0.0.1', dbname 'gtr_bd_archive');

CREATE USER MAPPING FOR role_source SERVER myserver
OPTIONS (user 'postgres', password 'secret');

Melden Sie sich vorzugsweise nicht als Superuser am Zielserver an. Verwenden Sie eine dedizierte Rolle mit eingeschränkten Rechten, um eine Rechteausweitung zu vermeiden.

Und verwenden Sie eine Passwortdatei auf dem Zielserver, um passwortlosen Zugriff zu ermöglichen. Auf diese Weise müssen Sie nicht einmal das Passwort in der USER MAPPING hinterlegen . Anweisungen im letzten Kapitel dieser verwandten Antwort:

Dann:

CREATE OR REPLACE FUNCTION pg_temp.flux_tresorerie_historique_backup_row()
  RETURNS trigger AS
$func$
BEGIN
   PERFORM dblink_connect('myserver');  -- name of foreign server from above

   PERFORM dblink_exec( format(
   $$
   INSERT INTO flux_tresorerie_historique  -- provide target column list!
   SELECT (r).id_flux_historique
        , (r).date_operation_flux
        , (r).date_valeur_flux
        , (r).date_rapprochement_flux::date  -- 'YYYY-MM-DD' is default ISO format anyway
        , (r).libelle_flux
        , (r).montant_flux
        , (r).contre_valeur_dzd
        , (r).rib_compte_bancaire
        , (r).frais_flux
        , (r).sens_flux
        , (r).statut_flux
        , (r).code_devise
        , (r).code_mode_paiement
        , (r).code_agence
        , (r).code_compte
        , (r).code_banque
        , (r).date_maj_flux
        , (r).statut_frais
        , (r).reference_flux
        , (r).code_commission
        , (r).id_flux
   FROM   (SELECT %L::flux_tresorerie_historique) t(r)
   $$, OLD::text));  -- cast whole row type

   PERFORM dblink_disconnect();
   RETURN NULL;  -- only for AFTER trigger
END
$func$  LANGUAGE plpgsql;

Sie sollten die Liste der Spalten für die Zieltabelle buchstabieren, wenn die Zeilentypen nicht übereinstimmen.

Wenn Sie das ernst meinen:

D.h. Sie fügen die ganze Zeile ein und der Zielzeilentyp identisch ist (kein Extrahieren eines Datums aus einem Zeitstempel usw.), können Sie das Übergeben der gesamten Zeile viel weiter vereinfachen.

CREATE OR REPLACE FUNCTION flux_tresorerie_historique_backup_row()
  RETURNS trigger AS
$func$
BEGIN
   PERFORM dblink_connect('myserver');  -- name of foreign server

   PERFORM dblink_exec( format(
   $$
   INSERT INTO flux_tresorerie_historique
   SELECT (%L::flux_tresorerie_historique).*
   $$
   , OLD::text));

   PERFORM dblink_disconnect();
   RETURN NULL;  -- only for AFTER trigger
END
$func$  LANGUAGE plpgsql;

Verwandte: