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

Postgresql:Bagaimana cara menghindari tanda kutip tunggal di pemicu Database?

Secara umum, kutipan diloloskan dengan menggandakannya.

Untuk menggabungkan variabel Anda ke dalam string SQL, Anda harus menggunakan quote_literal() - fungsi itu menangani pelepasan tanda kutip tunggal dengan benar, mis:

quote_literal(temp_row.row_data)

Karena itu:solusi yang lebih baik (dan lebih aman) adalah menggunakan parameter yang dikombinasikan dengan format() :

EXECUTE 
   format('INSERT INTO audit.%I_history values ($1, $2, $3)', tg_table_name)
   using temp_row.action_tstamp_tx, temp_row.action, temp_row.row_data; 

%I placeholder biasanya menangani pelepasan pengenal dengan benar, meskipun dalam kasus ini tidak akan berfungsi. Jika Anda ingin 100% yakin bahwa bahkan nama tabel non-standar berfungsi dengan baik, Anda harus terlebih dahulu memasukkan nama tabel target ke dalam variabel dan menggunakannya untuk format() fungsi:

l_tablename := TG_TABLE_NAME || '_history';
EXECUTE 
   format('INSERT INTO audit.%I_history values ($1, $2, $3)', l_tablename)
   using ....

Bagian ini:

v_sql = 'select * from ' || TG_TABLE_NAME::regclass || '_history';
execute v_sql into temp_row;

akan gagal setelah baris pertama juga. execute .. into ... mengharapkan kueri untuk mengembalikan tunggal . Pernyataan yang Anda gunakan akan mengembalikan semua baris dari tabel sejarah.

Saya juga tidak mengerti mengapa Anda melakukan itu sejak awal.

Anda tidak perlu memilih dari tabel riwayat sama sekali.

Sesuatu seperti ini seharusnya sudah cukup (belum diuji! ):

IF (TG_OP = 'UPDATE' AND TG_LEVEL = 'ROW') THEN
    temp_row := OLD;
ELSIF (TG_OP = 'DELETE' AND TG_LEVEL = 'ROW') THEN
    temp_row := OLD;
ELSIF (TG_OP = 'INSERT' AND TG_LEVEL = 'ROW') THEN
    temp_row := NEW;
ELSE
    RAISE EXCEPTION '[audit.if_modified] - Trigger func added as trigger for unhandled case: %, %',TG_OP, TG_LEVEL;
    RETURN NULL;
END IF;

execute format ('insert ... values ($1, $2, $3') 
   using now(), SUBSTRING(TG_OP,1,1), temp_row;

Terakhir:pemicu audit telah ditulis sebelumnya, dan ada banyak solusi siap pakai untuk ini:




  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 terbaik untuk menyimpan waktu sentuhan terakhir di Cassandra

  2. Bagaimana cara MENGUBAH tabel PostgreSQL dan membuat kolom menjadi unik?

  3. Ikhtisar Perubahan Indeks di PostgreSQL 11

  4. Menggunakan jsonb_set() untuk memperbarui nilai array jsonb tertentu

  5. Menggunakan pg_dump untuk hanya mendapatkan pernyataan penyisipan dari satu tabel dalam database