Anda mencampur sintaks untuk mengembalikan SETOF
nilai dengan sintaks untuk mengembalikan satu baris atau nilai.
-- Pertanyaan terkait adalah - bagaimana cara mengembalikan rekaman tunggal 'r' dari
Saat Anda mendeklarasikan fungsi dengan RETURNS TABLE
, Anda harus menggunakan RETURN NEXT
dalam tubuh untuk mengembalikan baris (atau nilai skalar). Dan jika Anda ingin menggunakan record
variabel dengan itu harus cocok jenis pengembalian. Lihat contoh kode di bawah.
Mengembalikan satu nilai atau baris
Jika Anda hanya ingin mengembalikan satu baris, tidak perlu untuk catatan jenis yang tidak ditentukan. @Kevin sudah menunjukkan dua cara. Saya akan menambahkan versi yang disederhanakan dengan OUT
parameter:
CREATE OR REPLACE FUNCTION my_func(OUT a integer, OUT b text)
AS
$func$
BEGIN
a := ...;
b := ...;
END
$func$ LANGUAGE plpgsql;
Anda bahkan tidak perlu menambahkan RETURN;
di badan fungsi, nilai yang dideklarasikan OUT
parameter akan dikembalikan secara otomatis di akhir fungsi - NULL
untuk parameter apa pun yang belum ditetapkan.
Dan Anda tidak perlu mendeklarasikan RETURNS RECORD
karena itu sudah jelas dari OUT
parameter.
Mengembalikan sekumpulan baris
Jika Anda benar-benar ingin mengembalikan beberapa baris (termasuk kemungkinan untuk 0 atau 1 baris), Anda dapat menentukan jenis pengembalian sebagai RETURNS
...
-
SETOF some_type
, di manasome_type
dapat berupa skalar terdaftar atau tipe komposit. -
TABLE (col1 type1, col2 type2)
- definisi tipe baris ad-hoc. -
SETOF record
ditambahOUT
parameter untuk menentukan nama dan jenis kolom.
100% setara denganRETURNS TABLE
. -
SETOF record
tanpa definisi lebih lanjut. Tapi kemudian baris yang dikembalikan tidak ditentukan dan Anda perlu menyertakan daftar definisi kolom dengan setiap panggilan (lihat contoh).
Manual tentang jenis catatan:
Variabel record mirip dengan variabel tipe baris, tetapi memiliki struktur yang tidak ditentukan sebelumnya. Mereka mengambil struktur baris sebenarnya dari baris yang ditugaskan selama perintah SELECT atau FOR.
Masih ada lagi, baca manual.
Anda bisa menggunakan variabel record tanpa menetapkan tipe yang ditentukan, Anda bisa bahkan mengembalikan catatan yang tidak ditentukan seperti itu:
CREATE OR REPLACE FUNCTION my_func()
RETURNS SETOF record AS
$func$
DECLARE
r record;
BEGIN
r := (1::int, 'foo'::text); RETURN NEXT r; -- works with undefined record
r := (2::int, 'bar'::text); RETURN NEXT r;
END
$func$ LANGUAGE plpgsql;
Telepon:
SELECT * FROM my_func() AS x(a int, b text);
Tapi ini sangat berat karena Anda harus memberikan daftar definisi kolom dengan setiap panggilan. Biasanya dapat diganti dengan sesuatu yang lebih elegan:
- Jika Anda mengetahui jenisnya pada saat pembuatan fungsi, nyatakan segera (
RETURNS TABLE
atau teman).
CREATE OR REPLACE FUNCTION my_func()
RETURNS SETOF tbl_or_type AS
$func$
DECLARE
r tbl_or_type;
BEGIN
SELECT INTO tbl_or_type * FROM tbl WHERE id = 10;
RETURN NEXT r; -- type matches
SELECT INTO tbl_or_type * FROM tbl WHERE id = 12;
RETURN NEXT r;
-- Or simpler:
RETURN QUERY
SELECT * FROM tbl WHERE id = 14;
END
$func$ LANGUAGE plpgsql;
- Jika Anda mengetahui tipe pada saat pemanggilan fungsi , ada cara yang lebih elegan menggunakan tipe polimorfik:
Refactor fungsi PL/pgSQL untuk mengembalikan output dari berbagai kueri SELECT
Pertanyaan Anda tidak jelas tentang apa yang sebenarnya Anda butuhkan.