PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Acesse o nome da coluna dinâmica do tipo de linha na função de gatilho


Isso deve servir:
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;

A causa imediata da mensagem de erro foi o SELECT externo . Sem destino, você precisa substituí-lo por PERFORM em plpgsql. Mas o PERFORM interno na string de consulta passada para EXECUTE também estava errado. PERFORM é um comando plpgsql, inválido em uma string SQL passada para EXECUTE , que espera código SQL. Você tem que usar SELECT lá. Finalmente OLD e NEW não são visíveis dentro de EXECUTE e cada um levantaria uma exceção própria do jeito que você fez. Todos os problemas são corrigidos descartando EXECUTE .

Uma maneira simples e rápida de obter o valor de um nome de coluna dinâmico dos tipos de linha OLD e NEW :converter para json , então você pode parametrizar o nome da chave como demonstrado. Deve ser um pouco mais simples e rápido que a alternativa com SQL dinâmico - o que também é possível, como:
  ...
  EXECUTE format('SELECT validate_bid_modifiers_count(table_name
                                                    , column_name
                                                    , ($1.%I)::bigint
                                                    , devices_count)', column_name)
  USING OLD;
  ...

Relacionado:

Aparte:Não sei por que você precisa das fechaduras pesadas.

Aparte 2:Considere escrever uma função de gatilho separada para cada gatilho. DDL mais barulhento, mas mais simples e rápido de executar.