sql >> Database >  >> RDS >> PostgreSQL

Generieke trigger om invoegingen te beperken op basis van aantal

Ik heb een soortgelijk type generieke triggers gedaan. Het meest lastige is om de waarde-invoer in de NEW te krijgen opnemen op basis van de kolomnaam.

Ik doe het op de volgende manier:

  • convert NEW gegevens in array;
  • vind de attnum van de kolom en gebruik het als een index voor de array.

Deze aanpak werkt zolang er geen komma's in de gegevens staan :( Ik ken geen andere manieren om NEW te converteren of OLD variabelen in de reeks waarden.

De volgende functie kan helpen:

CREATE OR REPLACE FUNCTION impose_maximum() RETURNS trigger AS $impose_maximum$
DECLARE
  _sql  text;
  _cnt  int8;
  _vals text[];
  _anum int4;
  _im   record;

BEGIN
 _vals := string_to_array(translate(trim(NEW::text), '()', ''), ',');

 FOR _im IN SELECT * FROM imposed_maximums WHERE table_name = TG_TABLE_NAME LOOP
  SELECT attnum INTO _anum FROM pg_catalog.pg_attribute a
    JOIN pg_catalog.pg_class t ON t.oid = a.attrelid
   WHERE t.relkind = 'r' AND t.relname = TG_TABLE_NAME
     AND NOT a.attisdropped AND a.attname = _im.column_group;

  _sql := 'SELECT count('||quote_ident(_im.column_count)||')'||
          ' FROM '||quote_ident(_im.table_name)||
          ' WHERE '||quote_ident(_im.column_group)||' = $1';

  EXECUTE _sql INTO _cnt USING _vals[_anum];

  IF _cnt > CAST(_im.max_size AS int8) THEN
    RAISE EXCEPTION 'Maximum of % hit for column % in table %(%=%)',
      _im.max_size, _im.column_count,
      _im.table_name, _im.column_group, _vals[_anum];
  END IF;
 END LOOP;

 RETURN NEW;
END; $impose_maximum$ LANGUAGE plpgsql;

Deze functie controleert alle voorwaarden die voor een bepaalde tabel zijn gedefinieerd.



  1. Perfect Storm voor het upgraden naar een moderne versie van SQL Server

  2. MS SQL Server en JDBC:gesloten verbinding

  3. optimaliseer mysql count-query

  4. Hoe afbeeldingen zoeken op naam in een map?