sql >> Database >  >> RDS >> PostgreSQL

Trigger om rijen in externe database in te voegen na verwijdering

Dit is een beperkte toepassing van replicatie. De vereisten variëren sterk, dus er zijn een aantal verschillende gevestigde oplossingen voor verschillende situaties. Bekijk het overzicht in de handleiding.

Uw handgebreide, op triggers gebaseerde oplossing is een haalbare optie voor relatief weinigen verwijderingen. Het openen en sluiten van een aparte verbinding voor elke rij brengt nogal wat overhead met zich mee. Er zijn andere verschillende opties.

Terwijl werken met dblink stel ik enkele wijzigingen voor. Het belangrijkste is:

  • Gebruik format() om op een elegantere manier aan strings te ontsnappen.

  • Passeer de hele rij in plaats van elke kolom te passeren en te ontsnappen.

  • Plaats het wachtwoord niet in elke afzonderlijke triggerfunctie.
    Gebruik een FOREIGN SERVER plus USER MAPPING . Gedetailleerde instructies hier:

Voer in principe één keer uit op de bronserver:

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

Log bij voorkeur niet in als superuser op de doelserver. Gebruik een speciale rol met beperkte bevoegdheden om escalatie van bevoegdheden te voorkomen.

En gebruik een wachtwoordbestand op de doelserver om toegang zonder wachtwoord mogelijk te maken. Op deze manier hoeft u niet eens het wachtwoord op te slaan in de USER MAPPING . Instructies in het laatste hoofdstuk van dit gerelateerde antwoord:

Dan:

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;

U moet de lijst met kolommen voor de doeltabel spellen als de rijtypen niet overeenkomen.

Als je dit serieus meent:

D.w.z. u voegt de hele rij . in en het type doelrij is identiek (geen datum extraheren uit een tijdstempel enz.), kunt u veel verder vereenvoudigen door de hele rij door te geven.

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;

Gerelateerd:



  1. Oracle 21c verbinden met SQL Server

  2. Pg_dump gebruiken om alleen insert-instructies uit één tabel binnen de database te krijgen

  3. Optimalisatie bij samenvoegen vanuit Oracle datalink

  4. Werken met PostgreSQL-databases