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

Få adgang til det dynamiske kolonnenavn på rækketypen i triggerfunktionen

Dette burde gøre det:

CREATE OR REPLACE FUNCTION device_bid_modifiers_count_per()
  RETURNS TRIGGER AS
$func$
DECLARE
   devices_count int      := device_types_count();
   table_name    regclass := TG_ARGV[0];
   column_name   text     := TG_ARGV[1];
BEGIN
   LOCK TABLE device_types IN EXCLUSIVE MODE;
   EXECUTE format('LOCK TABLE %s IN EXCLUSIVE MODE', table_name);

   IF TG_OP = 'DELETE' THEN
      PERFORM validate_bid_modifiers_count(table_name
                                         , column_name
                                         , (row_to_json(OLD) ->> column_name)::bigint
                                         , devices_count);
   ELSE
      PERFORM validate_bid_modifiers_count(table_name
                                         , column_name
                                         , (row_to_json(NEW) ->> column_name)::bigint
                                         , devices_count);
   END IF;

   RETURN NEW;
END
$func$  LANGUAGE plpgsql;

Den umiddelbare årsag til fejlmeddelelsen var den ydre SELECT . Uden mål skal du erstatte det med PERFORM i plpgsql. Men den indre PERFORM i forespørgselsstrengen sendt til EXECUTE var også forkert. PERFORM er en plpgsql-kommando, ikke gyldig i en SQL-streng sendt til EXECUTE , som forventer SQL-kode. Du skal bruge SELECT der. Endelig OLD og NEW er ikke synlige i EXECUTE og ville hver især rejse sin egen undtagelse, som du havde det. Alle problemer løses ved at droppe EXECUTE .

En enkel og hurtig måde at få værdien af ​​et dynamisk kolonnenavn fra rækketyperne OLD og NEW :cast til json , så kan du parametrere nøglenavnet som vist. Bør være en smule enklere og hurtigere end alternativet med dynamisk SQL - hvilket også er muligt, som:

  ...
  EXECUTE format('SELECT validate_bid_modifiers_count(table_name
                                                    , column_name
                                                    , ($1.%I)::bigint
                                                    , devices_count)', column_name)
  USING OLD;
  ...

Relateret:

Til side:Ikke sikker på, hvorfor du har brug for de tunge låse.

Bortset fra 2:Overvej at skrive en separat triggerfunktion for hver trigger i stedet. Mere støjende DDL, men enklere og hurtigere at udføre.



  1. Få det nye registrerings primære nøgle-id fra MySQL-indsættelsesforespørgsel?

  2. Sådan gulvnumre i SQL

  3. Udefineret indeks:REMOTE_ADDR mens Laravel migrerer

  4. PHP:Hvad er den hurtigste måde at forespørge på MySQL? Fordi PDO er smerteligt langsom