Das sollte es tun:
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;
Die unmittelbare Ursache für die Fehlermeldung war das äußere SELECT
. Ohne Ziel müssen Sie es durch PERFORM
ersetzen in plpgsql. Aber das innere PERFORM
in der an EXECUTE
übergebenen Abfragezeichenfolge war auch falsch. PERFORM
ist ein plpgsql-Befehl, nicht gültig in einer SQL-Zeichenfolge, die an EXECUTE
übergeben wird , die SQL-Code erwartet. Sie müssen SELECT
verwenden dort. Schließlich OLD
und NEW
sind innerhalb von EXECUTE
nicht sichtbar und würde jeder eine eigene Ausnahme auslösen, so wie Sie es hatten. Alle Probleme werden durch Ablegen von EXECUTE
behoben .
Eine einfache und schnelle Möglichkeit, den Wert eines dynamischen Spaltennamens abzurufen aus den Zeilentypen OLD
und NEW
:in json
umwandeln , dann können Sie den Schlüsselnamen wie gezeigt parametrisieren. Sollte etwas einfacher und schneller sein als die Alternative mit dynamischem SQL - was auch möglich ist, wie:
...
EXECUTE format('SELECT validate_bid_modifiers_count(table_name
, column_name
, ($1.%I)::bigint
, devices_count)', column_name)
USING OLD;
...
Verwandte:
- Holen Sie sich Werte aus verschiedenen Spalten in einem generischen Trigger
- Trigger mit dynamischem Feldnamen
Beiseite:Ich bin mir nicht sicher, warum Sie die schweren Schlösser brauchen.
Nebenbemerkung 2:Erwägen Sie stattdessen, für jeden Trigger eine separate Triggerfunktion zu schreiben. Lauteres DDL, aber einfacher und schneller auszuführen.