Ini bisa bekerja seperti ini:
CREATE OR REPLACE FUNCTION tt_query(orig_name regclass, data_tt timestamp)
RETURNS SETOF record AS
$func$
BEGIN
EXECUTE 'CREATE OR REPLACE TEMP VIEW tmp as
select *
from '
|| orig_name
|| ' where trigger_changed >'
|| quote_literal(data_tt)
|| ' ORDER BY trigger_changed DESC';
-- other work on view tmp
-- return the rows of view temp
RETURN QUERY
SELECT * FROM tmp;
END
$func$ LANGUAGE plpgsql;
-
Perhatikan penggunaan jenis pengenal objek
regclass
untuk menghindari injeksi SQL secara otomatis. -
Jangan gunakan sintaks lama
var ALIAS for $1
jika Anda tidak perlu. Deklarasikan nama parameter sebagai gantinya. -
Saya tidak akan menggunakan kata kunci
temp
sebagai pengidentifikasi, bahkan jika itu diizinkan. Menggunakantmp
sebagai gantinya. -
Gunakan
RETURN QUERY
untuk mengembalikan satu set catatan. Ini bahkan bisa menjadi panggilan statis tanpaEXECUTE
. Namun, Anda mengembalikan catatan anonim dan Postgres menuntut daftar definisi kolom dengan setiap panggilan:
SELECT * FROM tt_query('tbl_name', '2014-02-15 12:00')
AS f(col1 int, col2 text, ...);
Ini agak berat.
Solusi yang lebih baik
Jika Anda tahu tipe pengembalian (bahkan jika nama tabel berubah, daftar kolom mungkin memiliki tipe yang sama), nyatakan pada waktu pembuatan. Pertimbangkan pertanyaan terkait ini:
PostgreSQL:ERROR:42601:daftar definisi kolom diperlukan untuk fungsi yang mengembalikan "record"
Jika jenis pengembalian bervariasi dengan nama tabel yang disediakan, masih ada solusi yang jauh lebih baik. Karena Anda membuat tampilan dengan SELECT * FROM tbl
, Anda dapat menggunakan jenis tabel yang terkenal itu sendiri sebagai polimorfik
parameter:
CREATE OR REPLACE FUNCTION tt_query(orig_name anyelement, data_tt timestamp)
RETURNS SETOF anyelement AS
$func$
BEGIN
EXECUTE format('CREATE OR REPLACE TEMP VIEW tmp AS
SELECT * FROM %s
WHERE trigger_changed > %L
ORDER BY trigger_changed DESC'
,pg_typeof(orig_name)
,data_tt);
-- other work on view tmp
-- return the rows of view tmp
RETURN QUERY
SELECT * FROM tmp;
END
$func$ LANGUAGE plpgsql;
Panggilan Sederhana:
SELECT * FROM tt_query(NULL::tbl_name, '2014-02-15 12:00');
Juga menggunakan format()
untuk penggabungan string yang aman &sederhana.
Detail lebih lanjut dalam jawaban terkait ini:
Memfaktorkan ulang fungsi PL/pgSQL untuk mengembalikan output dari berbagai kueri SELECT