PostgreSQL
 sql >> Teknologi Basis Data >  >> RDS >> PostgreSQL

Akses nama kolom dinamis dari jenis baris dalam fungsi pemicu

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.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Cara paling efisien untuk menemukan titik dalam radius tertentu dari titik tertentu

  2. Pemicu postgres setelah memasukkan mengakses BARU

  3. konversi nilai kolom jsonb ke beberapa kolom di PostgreSQL

  4. Apakah PostgreSQL menyimpan penerjemah pl*-nya terus-menerus dimuat?

  5. Mengapa urutan tidak diperbarui saat SALIN dilakukan di PostgreSQL?