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
dantable_name
sebagai parameter untuk berfungsi dan mendapatkan daftar record, menurutcolumn_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?
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.