Ini harus melakukannya:
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;
Penyebab langsung untuk pesan kesalahan adalah SELECT outer luar . Tanpa target, Anda perlu menggantinya dengan PERFORM di plgsql. Tapi bagian dalam PERFORM dalam string kueri yang diteruskan ke EXECUTE juga salah. PERFORM adalah perintah plpgsql, tidak valid dalam string SQL yang diteruskan ke EXECUTE , yang mengharapkan kode SQL. Anda harus menggunakan SELECT di sana. Akhirnya OLD dan NEW tidak terlihat di dalam EXECUTE dan masing-masing akan memunculkan pengecualian mereka sendiri seperti yang Anda miliki. Semua masalah diperbaiki dengan menghapus EXECUTE .
Cara sederhana dan cepat untuk mendapatkan nilai nama kolom dinamis dari baris ketik OLD dan NEW :dilemparkan ke json , maka Anda dapat membuat parameter nama kunci seperti yang ditunjukkan. Harus sedikit lebih sederhana dan lebih cepat daripada alternatif dengan SQL dinamis - yang mungkin juga, seperti:
...
EXECUTE format('SELECT validate_bid_modifiers_count(table_name
, column_name
, ($1.%I)::bigint
, devices_count)', column_name)
USING OLD;
... Terkait:
Selain:Tidak yakin mengapa Anda membutuhkan kunci yang berat.
Selain 2:Pertimbangkan untuk menulis fungsi pemicu terpisah untuk setiap pemicu. DDL yang lebih berisik, tetapi lebih sederhana dan lebih cepat untuk dieksekusi.