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

Přístup k názvu dynamického sloupce typu řádku ve funkci spouštění

Mělo by to stačit:

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;

Bezprostřední příčinou chybové zprávy byl vnější SELECT . Bez cíle jej musíte nahradit výrazem PERFORM v plpgsql. Ale vnitřní PERFORM v řetězci dotazu předaném EXECUTE se také mýlil. PERFORM je příkaz plpgsql, který není platný v řetězci SQL předávaném EXECUTE , který očekává kód SQL. Musíte použít SELECT tam. Konečně OLD a NEW nejsou viditelné uvnitř EXECUTE a každý by vyvolal svou vlastní výjimku, jak jste to měli vy. Všechny problémy jsou vyřešeny zrušením EXECUTE .

Jednoduchý a rychlý způsob, jak získat hodnotu názvu dynamického sloupce z typů řádků OLD a NEW :přenést do json , pak můžete parametrizovat název klíče, jak je ukázáno. Mělo by to být o něco jednodušší a rychlejší než alternativa s dynamickým SQL – což je také možné, jako:

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

Související:

Stranou:Nejste si jisti, proč potřebujete těžké zámky.

Vedle 2:Zvažte místo toho napsat samostatnou funkci spouštění pro každý spouštěč. Hlučnější DDL, ale jednodušší a rychlejší na provedení.



  1. Jak vytvořit stromovou tabulku bez cyklického vztahu?

  2. Optimalizujte dotaz MySQL UPDATE, který obsahuje WHERE a ORDER BY?

  3. SQLite - příkazy JOIN

  4. Stránkovat Wordpress $wpdb dotaz?