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

Gunakan variabel yang disetel oleh perintah meta psql di dalam blok DO

Jawab

DO mengharapkan string literal dengan kode plpgsql. Simbol tidak diganti di dalam string di psql.
Anda dapat menggabungkan seluruh string menjadi variabel psql dan lalu jalankan.

  • Bagaimana cara menggabungkan variabel psql?

Format multi-baris yang cantik tidak dimungkinkan, karena (per dokumentasi):

Namun bagaimanapun juga, argumen dari meta-command tidak dapat dilanjutkan di luar akhir baris.

Contoh sederhana:

test=# \set value foo
test=# \set do 'BEGIN\n   RAISE NOTICE ''v: %'', ' :'value' ';\nEND'
test=# DO :'do';
NOTICE:  v: foo

Ganti jeda baris dengan \n (atau hapus jika Anda tidak peduli dengan format yang cantik). Berdasarkan kode yang diadaptasi ini:

DO
'
DECLARE
   _val  text;
   _vals text[] := string_to_array(>>values<<, '','');
BEGIN
   FOREACH _val IN ARRAY _vals
   LOOP
     RAISE NOTICE ''v: %'', _val;
   END LOOP;
END
'

Tampilannya seperti ini:

test=# \set do 'DECLARE\n   _val  text;\n   _vals text[] := string_to_array(' :'values' ', '','');\nBEGIN\n   FOREACH _val IN ARRAY _vals\n   LOOP\n     RAISE NOTICE ''v: %'', _val;\n   END LOOP;\nEND'
test=# DO :'do';
NOTICE:  v: foo
NOTICE:  v: bar
NOTICE:  v: baz
DO

Saya menambahkan tebal penekanan pada variabel agar lebih mudah dikenali.

Jawaban terkait oleh @Pavel (ab)menggunakan variabel sesi server:

  • Merujuk ke variabel sesi (\set var='value') dari PL/PGSQL

Solusi alternatif

Pernyataan yang disiapkan

Solusi Anda saat ini tidak terlihat buruk. Saya akan menyederhanakan:

PREPARE get_values AS SELECT * FROM regexp_split_to_table(:'values', ',');

DO
$do$
DECLARE
   _val text;
BEGIN
   FOR _val IN EXECUTE
      'EXECUTE get_values'
   LOOP
      RAISE NOTICE 'v: %', _val;
   END LOOP;
END
$do$;

Tabel sementara

Solusi serupa dengan tabel sementara:

CREATE TEMP TABLE tmp AS SELECT * FROM regexp_split_to_table(:'values', ',') v;

DO
$do$
DECLARE
   _val text;
BEGIN
   FOR _val IN
      TABLE tmp
   LOOP
      RAISE NOTICE 'v: %', _val;
   END LOOP;
END
$do$;


  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 lebih baik membuat indeks sebelum mengisi tabel dengan data, atau setelah data ada?

  2. Mengubah banyak baris menjadi kolom di PostgreSQL

  3. heroku, postgreSQL, Django, comments, deliciouspie:Tidak ada operator yang cocok dengan nama dan tipe argumen yang diberikan. Anda mungkin perlu menambahkan gips tipe eksplisit

  4. Pilih catatan pertama jika tidak ada yang cocok

  5. Bagaimana cara membulatkan rata-rata menjadi 2 tempat desimal di PostgreSQL?