Triggers

  • Triggere i databasen aktiverer funktioner i forbindelse med begivenheder på databasen. I det følgende gennemgår vi tabel-triggere som aktiveres ved INSERT, UPDATE og DELETE statements

  • Principielt findes tre typer triggere:

    • Before
    • After
    • Instead of

Before

Before bruges typisk når "noget" skal laves om på de data, der ændres / sættes ind eller noget skal tilføjes.

Eksempel: Beregn arealet af en geometri ved hver INSERT/UPDATE

ALTER TABLE att0902.bygninger ADD COLUMN area double precision;

CREATE OR REPLACE FUNCTION calc_area()
RETURNS trigger AS
$BODY$
BEGIN
  NEW.area := st_area(NEW.geom);
  RETURN NEW;
END;
$BODY$
LANGUAGE plpgsql;

CREATE TRIGGER bygninger_area_trig BEFORE INSERT OR UPDATE ON att0902.bygninger
  FOR EACH ROW EXECUTE PROCEDURE calc_area();

SELECT * FROM att0902.bygninger ;

INSERT INTO att0902.bygninger(
            geom, "Info", "Objekttype", "Z", "Konverteret")
    VALUES (ST_GeomFromText('POLYGON((390309.70572787 7538535.16303447,390306.811436522 7538533.90329089,390307.759708616 7538531.72373453,390304.79120467 7538530.44399502,390308.015329789 7538522.94552131,390322.478540685 7538529.21424533,390319.097744523 7538536.62273735,390310.637508276 7538532.97348015,390309.70572787 7538535.16303447))',32622),
     '--', 'SKUR', 66.66, '20110110');

Trigger der opdaterer et materialized view når underliggende tabeller opdateres

CREATE OR REPLACE FUNCTION trig_refresh_lokationer_mv()
  RETURNS trigger AS
$BODY$
BEGIN

    REFRESH MATERIALIZED VIEW trap.lokationer_mv;
    REFRESH MATERIALIZED VIEW trap.lokationer_mv_point;
    RETURN NULL;
END;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;
ALTER FUNCTION trig_refresh_lokationer_mv()
  OWNER TO trap;


CREATE TRIGGER trig_01_refresh_lokationer_mv AFTER TRUNCATE OR INSERT OR UPDATE OR DELETE
   ON trap.egne_punkter  FOR EACH STATEMENT
   EXECUTE PROCEDURE trig_refresh_lokationer_mv();

Trigger der opdaterer en flades arbejdssted (udfra en anden polygon). Håndterer også hvis flere flader overlappes

DROP TRIGGER IF EXISTS gartner_flade_arbejdssted ON gartner.flade;
CREATE TRIGGER gartner_flade_arbejdssted
  BEFORE INSERT OR UPDATE
  ON gartner.flade
  FOR EACH ROW
  EXECUTE PROCEDURE gartner.flade_arbejdssted_trg();

CREATE OR REPLACE FUNCTION gartner.flade_arbejdssted_trg()
  RETURNS trigger AS
$BODY$
  BEGIN
    IF (TG_OP = 'UPDATE') THEN
      -- Insert punkt
      IF NEW.arbejdssted is NULL THEN
      NEW.arbejdssted =  (SELECT
          a.arbejdssted_id
          FROM  gartner.arbejdssted a
            WHERE st_intersects(NEW.geometry,a.geometry)
            ORDER BY st_Area(st_intersection(a.geometry,NEW.geometry)) DESC LIMIT 1);

      RETURN NEW;
      END IF;
      RETURN NEW;
    ELSIF (TG_OP = 'INSERT') THEN
       IF NEW.arbejdssted is NULL THEN
        NEW.arbejdssted =  (SELECT
          a.arbejdssted_id
          FROM  gartner.arbejdssted a
            WHERE st_intersects(NEW.geometry,a.geometry)
            ORDER BY st_Area(st_intersection(a.geometry,NEW.geometry)) DESC LIMIT 1);
      RETURN NEW;
        END IF;
      RETURN NEW;
    END IF;
  END;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;

Trigger der automatisk opdaterer en kolonne med timestamp


ALTER TABLE raw_data.parkarealer_region
  ADD COLUMN senest_opdateret TIMESTAMP;

CREATE OR REPLACE FUNCTION update_senest_opdateret_column()
RETURNS TRIGGER AS $$
BEGIN
    NEW.senest_opdateret = now();
    RETURN NEW;
END;
$$ language 'plpgsql';

CREATE TRIGGER update_park_modtime
 BEFORE UPDATE ON  raw_data.parkarealer_region
  FOR EACH ROW EXECUTE PROCEDURE  update_senest_opdateret_column();
  • Eksempler:
    • Etabler centroide punkt når geometrien ændres indsættes
    • Implementer forretningsregler (f.eks. "Arealet af en polygon må ikke være større end det definerede maksimum for objekttypen (defineret i en anden tabel)

After

Typisk når "noget" skal tilføjes i forbindelse med en operation

  • Eksempel:
    • Vedligehold en "log" tabel over alle de operationer, der foretages

Instead of

  • Eksempler:
    • I stedet for at indsætte en række i et view, indsæt i de underliggende tabeller
    • "Rejs" en fejl når det er forbudt at slette i en tabel (også for administrator)

Øvelse

Tilføj et arealfelt til bygningstabellen (integer). Byg en trigger til tabellen, der automatisk opdaterer feltet når man tegner en ny bygning.

Brug gerne den funktion du byggede i funktions-øvelsen.

Extra credit, hvis du har masser af tid

Modificer din afrundingsfunktion til at tage en ekstra parameter, p. Hvis p. er 1 fungerer den som før, dvs. til nærmeste heltalt. Hvis p er 5 bliver der afrundet til nærmeste 5'er (dvs. 49 bliver til 50 og 83 bliver til 85).

Opdater triggerfunktionen til at afrunde til nærmeste heltal på små bygninger, nærmeste 5'er på mellemstore bygninger og nærmeste 10'er på store bygninger.

results matching ""

    No results matching ""