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

Apakah ada sintaks keluar untuk variabel psql di dalam fungsi PostgreSQL?

PSQL SET variabel tidak diinterpolasi di dalam string yang dikutip dolar. Saya tidak tahu pasti, tapi saya pikir tidak ada jalan keluar atau tipu daya lain untuk mengaktifkan SET interpolasi variabel di sana.

Orang mungkin berpikir Anda dapat memasang :user yang tidak dikutip antara dua bentangan PL/pgSQL yang dikutip dolar untuk mendapatkan efek yang diinginkan. Tapi ini sepertinya tidak berhasil... Saya pikir sintaksnya membutuhkan string tunggal dan bukan string yang menggabungkan ekspresi. Mungkin salah dalam hal itu.

Bagaimanapun, itu tidak masalah. Ada pendekatan lain (seperti yang dicatat Pasco):tulis prosedur tersimpan untuk menerima argumen PL/pgSQL. Begini tampilannya.

CREATE OR REPLACE FUNCTION foo("user" TEXT) RETURNS void AS
$$
BEGIN
        EXECUTE 'GRANT SELECT ON my_table TO GROUP ' || quote_ident(user);
END;    
$$ LANGUAGE plpgsql;

Catatan tentang fungsi ini:

  1. EXECUTE menghasilkan GRANT . yang sesuai pada setiap doa menggunakan argumen prosedur kami. Bagian manual PG yang disebut "Melaksanakan Perintah Dinamis " menjelaskan EXECUTE secara rinci.
  2. Deklarasi argumen prosedur user harus dikutip ganda. Tanda kutip ganda memaksanya untuk ditafsirkan sebagai pengenal.

Setelah Anda mendefinisikan fungsi seperti ini, Anda dapat memanggilnya menggunakan variabel PSQL yang diinterpolasi. Berikut garis besarnya.

  1. Jalankan psql --variable user="'whoever'" --file=myscript.sql . Kutipan tunggal diperlukan di sekitar nama pengguna!
  2. Di myscript.sql, tentukan fungsi seperti di atas.
  3. Di myscript.sql, masukkan select foo(:user); . Di sinilah kami mengandalkan tanda kutip tunggal yang kami masukkan ke dalam nilai user .

Meskipun ini tampaknya berhasil, menurut saya ini agak squirrely. Saya pikir SET variabel dimaksudkan untuk konfigurasi runtime. Membawa data dalam SET sepertinya aneh.

Sunting :inilah alasan konkret untuk tidak gunakan SET variabel. Dari halaman manual:"Penugasan ini dilakukan selama tahap awal startup, jadi variabel yang dicadangkan untuk keperluan internal mungkin akan ditimpa nanti." Jika Postgres memutuskan untuk menggunakan variabel bernama user (atau apa pun yang Anda pilih), itu bisa menimpa argumen skrip Anda dengan sesuatu yang tidak pernah Anda maksudkan. Sebenarnya, psql sudah mengambil USER untuk dirinya sendiri -- ini hanya berfungsi karena SET peka huruf besar/kecil. Ini hampir merusak segalanya sejak awal!



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Apakah mungkin untuk mendefinisikan variabel global di postgresql

  2. pagination dan filtering pada tabel yang sangat besar di postgresql (keyset pagination?)

  3. Cara Mendaftar Semua Tampilan di Database PostgreSQL

  4. Perbedaan antara substring di Postgresql

  5. Bagaimana cara terhubung ke localhost dengan postgres_fdw?