sql >> Databáze >  >> RDS >> PostgreSQL

Jak se vyhnout opakování spouštěcích volání v PostgreSQL 9.2.1

Můžete to provést pomocí standardních spouštěčů BEFORE UPDATE OF ... ON ... .
Manuál k CREATE TRIGGER informuje:

Spouštěč se spustí, pouze pokud je alespoň jeden z uvedených sloupců uveden jako cíl příkazu UPDATE.

A dále:

Spouštěč specifický pro sloupec (definovaný pomocí syntaxe UPDATE OF column_name) se spustí, když je některý z jeho sloupců uveden jako cíl v seznamu SET příkazu UPDATE. Je možné, že se hodnota sloupce změní, i když se pravidlo nespustí, protože změny provedené v obsahu řádku spouštěči BEFORE UPDATE se neberou v úvahu.

Odvážný důraz můj. Takže žádné nekonečné smyčky, protože aktualizace uvnitř spouštěče nevyvolávají další spouštěč.

Testovací případ

Vytvořte testovací tabulku (zjednodušená, bez irelevantních řádků):

CREATE TABLE soil_samples (
  pgid SERIAL PRIMARY KEY

 ,utm_zone integer
 ,utm_easting integer
 ,utm_northing integer

 ,wgs84_longitude double precision
 ,wgs84_latitude double precision

 ,yt_albers_geom double precision
);

Umělý spouštěč pro váš první požadavek:

Když je provedena aktualizace utm_zone , utm_easting nebo utm_northing a poté wgs_84_latitude , wgs84_longitude a yt_albers_geom jsou aktualizovány spouštěčem.

CREATE OR REPLACE FUNCTION trg_upbef_utm()  RETURNS trigger AS
$func$
BEGIN
   NEW.wgs84_latitude  := NEW.wgs84_latitude + 10;
   NEW.wgs84_longitude := NEW.wgs84_longitude + 10;
   NEW.yt_albers_geom  := NEW.yt_albers_geom + 10;

   RETURN NEW;
END
$func$ LANGUAGE plpgsql;

CREATE TRIGGER upbef_utm
BEFORE UPDATE OF utm_zone, utm_easting, utm_northing ON soil_samples
FOR EACH ROW
WHEN (NEW.utm_zone     IS DISTINCT FROM OLD.utm_zone    OR
      NEW.utm_easting  IS DISTINCT FROM OLD.utm_easting OR
      NEW.utm_northing IS DISTINCT FROM OLD.utm_northing)  -- optional
EXECUTE PROCEDURE trg_upbef_utm();

WHEN doložka je nepovinná. Zabraňuje spuštění spouště, když se ve skutečnosti žádná hodnota nezměnila.

Umělý spouštěč pro váš druhý požadavek:

Po provedení aktualizace wgs84_latitude nebo wgs84_longitude , pak všechny utm_ pole jsou aktualizována, stejně jako yt_albers_geom .

CREATE OR REPLACE FUNCTION trg_upbef_wgs84()  RETURNS trigger AS
$func$
BEGIN
   NEW.utm_zone       := NEW.utm_zone + 100;
   NEW.utm_easting    := NEW.utm_easting + 100;
   NEW.utm_northing   := NEW.utm_northing + 100;
   NEW.yt_albers_geom := NEW.yt_albers_geom + 100;

   RETURN NEW;
END
$func$ LANGUAGE plpgsql;

CREATE TRIGGER upbef_wgs84
 BEFORE UPDATE OF wgs84_latitude, wgs84_longitude ON soil_samples
 FOR EACH ROW
 WHEN (NEW.wgs84_latitude  IS DISTINCT FROM OLD.wgs84_latitude OR
       NEW.wgs84_longitude IS DISTINCT FROM OLD.wgs84_longitude)  -- optional
 EXECUTE PROCEDURE trg_upbef_wgs84();

Spustit pro třetí požadavek v tomto smyslu ...

Test

INSERT INTO soil_samples VALUES (1, 1,1,1, 2,2, 3) RETURNING *;

Spusťte upbef_utm :prázdná aktualizace, nic se neděje:

UPDATE soil_samples SET utm_zone = 1 RETURNING *;

Aktualizace se skutečnou změnou:Druhý spouštěč upbef_wgs84 nespustí se UPDATE OF utm_zone !

UPDATE soil_samples SET utm_zone = 0 RETURNING *;

Spusťte upbef_wgs84 :

UPDATE soil_samples SET wgs84_latitude = 0 RETURNING *;

-> Ukázka SQLfiddle.




  1. Získejte hodnoty z prvního a posledního řádku na skupinu

  2. Jaká je minimální velikost klienta požadovaná pro připojení C# k databázi Oracle?

  3. Chyba 101 „Dotaz není povolen v aplikaci Waitfor“ na serveru SQL

  4. Při výběru a zakódování základního 64 obrázku z databáze byla zjištěna pomalost