PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

Достъп до динамично име на колона от тип ред във функция за задействане

Това трябва да го направи:

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;

Непосредствената причина за съобщението за грешка беше външният SELECT . Без target, трябва да го замените с PERFORM в plpgsql. Но вътрешният PERFORM в низа на заявката, предаван на EXECUTE също беше грешен. PERFORM е plpgsql команда, не е валидна в SQL низ, предаден на EXECUTE , който очаква SQL код. Трябва да използвате SELECT там. Най-накрая OLD и NEW не се виждат в EXECUTE и всеки би издигнал свое собствено изключение, както го направихте вие. Всички проблеми се коригират чрез премахване на EXECUTE .

Лесен и бърз начин да получите стойността на име на динамична колона от типовете редове OLD и NEW :прехвърляне към json , тогава можете да параметризирате името на ключа, както е показано. Трябва да е малко по-просто и по-бързо от алтернативата с динамичен SQL - което също е възможно, като:

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

Свързани:

Настрана:Не съм сигурен защо ви трябват тежките ключалки.

Освен 2:Помислете вместо това да напишете отделна тригерна функция за всеки тригер. По-шумен DDL, но по-прост и по-бърз за изпълнение.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Функция STRING_AGG() в PostgreSQL

  2. Преобразуване на колони на pandas в списък на PostgreSQL?

  3. postgres - ГРЕШКА:операторът не съществува

  4. Опашка за задания като SQL таблица с множество потребители (PostgreSQL)

  5. Как да търсите конкретна стойност във всички таблици (PostgreSQL)?