Saya menggunakan Postgresql 9.1, dengan ubuntu 12.04.
Terinspirasi oleh jawaban Craig untuk pertanyaan saya Penggabungan jenis setof atau merekam setof saya pikir saya akan pergi baik dengan menggunakan return query
, setof record
dan generator seri ke dalam fungsi plpgsql ini:
create or replace function compute_all_pair_by_craig(id_obj bigint)
returns setof record as $$
begin
return query select o.id, generate_series(0,o.value) from m_obj as o;
end;
$$ language plpgsql;
Selama eksekusi saya mendapatkan kesalahan:
ERROR: set_valued function called in context that cannot accept a set
Apa yang salah ? Bertentangan dengan Craig, saya memberi tahu fungsi untuk kembali setof record
.
Saya dapat mencapai sesuatu yang berfungsi persis seperti Craig, yaitu dengan mendefinisikan suatu tipe create type pair_id_value as (idx bigint, value integer)
dan membuat fungsi plpgsql saya mengembalikan sebuah setof of pair_id_value
alih - alih a setof record
.
Tetapi bahkan dengan solusi yang berfungsi ini, saya masih tidak mengerti mengapa select id, generate_series(0,13)
sendirian akan mengembalikan hasil dalam dua kolom ... dan sebaliknya memanggil fungsi (mengembalikan setof pair_id_value) dengan return query select id, generate_series(0,my_obj.value) from my_obj
akan mengembalikan hasil hanya dalam satu kolom yang bidangnya terlihat seperti ini "(123123,0)" "(123123,1)" "(123123,2)" (3 baris) yang merupakan tupel jelas.
Apakah ini kasus di mana tabel sementara harus / harus dibuat?
sumber
BEGIN
dan titik hilang setelahRETURN QUERY
. Setelah memperbaiki kesalahan-kesalahan itu saya mengkonfirmasi kesalahan ketika kembalirecord
; akan menjelaskan jawaban.Jawaban:
Pesan kesalahan sangat tidak membantu:
tetapi jika Anda mengulangi kueri untuk menyebutnya sebagai fungsi set-return yang tepat, Anda akan melihat masalah sebenarnya:
Jika Anda menggunakan
SETOF RECORD
tanpaOUT
daftar parameter, Anda harus menentukan hasil dalam pernyataan panggilan, misalnya:Namun, lebih baik menggunakan
RETURNS TABLE
atauOUT
parameter. Dengan sintaks sebelumnya, fungsi Anda adalah:Ini bisa dipanggil dalam konteks daftar SELECT dan dapat digunakan tanpa membuat tipe secara eksplisit atau menentukan struktur hasil di situs panggilan.
Adapun bagian kedua dari pertanyaan, apa yang terjadi adalah bahwa kasus pertama menentukan dua kolom terpisah dalam daftar SELECT, sedangkan yang kedua mengembalikan komposit tunggal. Ini sebenarnya tidak ada hubungannya dengan bagaimana Anda mengembalikan hasilnya, tetapi bagaimana Anda menjalankan fungsi. Jika kita membuat fungsi sampel:
Anda akan melihat perbedaan dalam dua cara untuk memanggil fungsi set-return - dalam
SELECT
daftar, ekstensi non-standar spesifik PostgreSQL dengan perilaku unik:atau sebagai tabel dengan cara yang lebih standar:
sumber
returns table
.