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.