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.