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

Berfungsi untuk mengembalikan kumpulan kolom dinamis untuk tabel yang diberikan

Solusi untuk kasus sederhana

Seperti yang dijelaskan dalam jawaban yang dirujuk di bawah, Anda dapat menggunakan tipe terdaftar (baris), dan dengan demikian secara implisit mendeklarasikan tipe kembalian fungsi polimorfik:

CREATE OR REPLACE FUNCTION public.get_table(_tbl_type anyelement)
  RETURNS SETOF anyelement AS
$func$
BEGIN
   RETURN QUERY EXECUTE format('TABLE %s', pg_typeof(_tbl_type));
END
$func$ LANGUAGE plpgsql;

Telepon:

SELECT * FROM public.get_table(NULL::public.users);  -- note the syntax!

Mengembalikan tabel lengkap (dengan semua kolom pengguna).

Tunggu! Bagaimana?

Penjelasan terperinci dalam jawaban terkait ini, bab"Berbagai jenis tabel lengkap" :

  • Memfaktorkan ulang fungsi PL/pgSQL untuk mengembalikan output dari berbagai kueri SELECT

TABLE foo singkatan dari SELECT * FROM foo :

  • Apakah ada jalan pintas untuk SELECT * FROM?

2 langkah-langkah untuk tipe pengembalian yang sepenuhnya dinamis

Tapi apa yang Anda coba lakukan adalah sangat tidak mungkin dalam tunggal Perintah SQL.

Saya ingin melewati schema_name dan table_name sebagai parameter untuk berfungsi dan mendapatkan daftar record, menurut column_visible bidang dipublic.fields tabel.

Tidak ada cara langsung untuk mengembalikan pilihan kolom yang sewenang-wenang (tipe pengembalian tidak diketahui pada waktu panggilan) dari suatu fungsi - atau apa saja perintah SQL. SQL menuntut untuk mengetahui nomor, nama, dan jenis kolom yang dihasilkan pada waktu panggilan. Selengkapnya di bab ke-2 dari jawaban terkait ini:

  • Bagaimana cara menghasilkan CROSS JOIN berporos di mana definisi tabel yang dihasilkan tidak diketahui?

Ada berbagai solusi . Anda dapat membungkus hasilnya dalam salah satu jenis dokumen standar (json , jsonb , hstore , xml ).

Atau Anda membuat kueri dengan satu panggilan fungsi dan menjalankan hasilnya dengan yang berikutnya:

CREATE OR REPLACE FUNCTION public.generate_get_table(_schema_name text, _table_name text)
  RETURNS text AS
$func$
   SELECT format('SELECT %s FROM %I.%I'
               , string_agg(quote_ident(column_name), ', ')
               , schema_name
               , table_name)
   FROM   fields
   WHERE  column_visible
   AND    schema_name = _schema_name 
   AND    table_name  = _table_name
   GROUP  BY schema_name, table_name
   ORDER  BY schema_name, table_name;
$func$  LANGUAGE sql;

Telepon:

SELECT public.generate_get_table('public', 'users');

Ini membuat kueri dalam bentuk:

SELECT usr_id, usr FROM public.users;

Jalankan di langkah ke-2. (Anda mungkin ingin menambahkan nomor kolom dan mengurutkan kolom.)
Atau tambahkan \gexec di psql untuk mengeksekusi nilai kembalian segera. Lihat:

Bagaimana memaksa evaluasi subquery sebelum bergabung / menekan ke server asing

Pastikan untuk bertahan melawan injeksi SQL:

  • MASUKKAN dengan nama tabel dinamis dalam fungsi pemicu
  • Tentukan nama tabel dan kolom sebagai argumen dalam fungsi plpgsql?
Selain itu

varchar(100) tidak masuk akal untuk pengidentifikasi, yang dibatasi hingga 63 karakter dalam Postgres standar:

  • Karakter maksimum dalam label (nama tabel, kolom, dll.)

Jika Anda memahami bagaimana pengidentifikasi objek mengetik regclass berfungsi, Anda dapat mengganti nama skema dan tabel dengan regclass sing kolom.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Tambahkan Tahun ke Tanggal di PostgreSQL

  2. Memperbarui JLabel melalui SetIcon dari tipe data bytea di postgres

  3. Cara Menyebarkan PostgreSQL yang Sangat Tersedia dengan Titik Akhir Tunggal untuk WordPress

  4. ID penetapan otomatis Rails yang sudah ada

  5. Pembagian bilangan bulat mengembalikan 0