sql >> Database teknologi >  >> RDS >> PostgreSQL

Trigger for at indsætte rækker i fjerndatabasen efter sletning

Dette er en begrænset anvendelse af replikation. Kravene varierer meget, så der er en række forskellige etablerede løsninger, der adresserer forskellige situationer. Overvej oversigten i manualen.

Din håndstrikkede, trigger-baserede løsning er en levedygtig mulighed for relativt sletninger. Åbning og lukning af en separat forbindelse for hver række medfører en del overhead. Der er andre forskellige muligheder.

Mens arbejder med dblink foreslår jeg nogle ændringer. Vigtigst af alt:

  • Brug format() at undslippe strenge mere elegant.

  • Gå forbi hele rækken i stedet for at passere og undslippe hver eneste kolonne.

  • Anbring ikke adgangskoden i hver enkelt triggerfunktion.
    Brug en FOREIGN SERVER plus USER MAPPING . Detaljerede instruktioner her:

Grundlæggende skal du køre en gang på kildeserveren:

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 helst ikke ind som superbruger på målserveren. Brug en dedikeret rolle med begrænsede rettigheder for at undgå eskalering af privilegier.

Og brug en adgangskodefil på målserveren for at tillade adgang uden adgangskode. På denne måde behøver du ikke engang at gemme adgangskoden i USER MAPPING . Instruktioner i det sidste kapitel af dette relaterede svar:

Så:

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;

Du bør udskrive listen over kolonner for måltabellen, hvis rækketyperne ikke stemmer overens.

Hvis du mener det seriøst:

Dvs., du indsætter hele rækken og målrækketypen er identisk (ingen udtrækning af en dato fra et tidsstempel osv.), kan du forenkle meget mere ved at passere hele rækken.

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;

Relateret:



  1. Crystal Reports vs. Microsoft SQL Server Reporting Services

  2. MySQL-fejlkode 1452 Foreign Key Constraint

  3. Rails 3 app med PostgreSQL - Få listen over beskeder grupperet efter konvertering

  4. SQL, spørgsmål om joinforbindelse