Saya memiliki fungsi ini di PostgreSQL, tetapi saya tidak tahu cara mengembalikan hasil kueri:
CREATE OR REPLACE FUNCTION wordFrequency(maxTokens INTEGER)
RETURNS SETOF RECORD AS
$$
BEGIN
SELECT text, count(*), 100 / maxTokens * count(*)
FROM (
SELECT text
FROM token
WHERE chartype = 'ALPHABETIC'
LIMIT maxTokens
) as tokens
GROUP BY text
ORDER BY count DESC
END
$$
LANGUAGE plpgsql;
Tapi saya tidak tahu bagaimana mengembalikan hasil kueri di dalam fungsi PostgreSQL.
Saya menemukan bahwa tipe pengembalian seharusnya SETOF RECORD
, bukan? Tetapi perintah kembali tidak benar.
Bagaimana cara yang benar untuk melakukan ini?
sql
postgresql
return
plpgsql
return-type
Renato Dinhani
sumber
sumber
LANGUAGE SQL
.Jawaban:
Penggunaan
RETURN QUERY
:Panggilan:
Penjelasan:
Hal ini jauh lebih praktis secara eksplisit menentukan jenis kembali dari sekedar menyatakan sebagai rekor. Dengan cara ini Anda tidak perlu menyediakan daftar definisi kolom dengan setiap panggilan fungsi.
RETURNS TABLE
adalah salah satu cara untuk melakukannya. Ada yang lainnya. Tipe dataOUT
parameter harus sama persis dengan apa yang dikembalikan oleh kueri.Pilih nama untuk
OUT
parameter dengan hati-hati. Mereka terlihat di tubuh fungsi hampir di mana saja. Kolom kualifikasi tabel dengan nama yang sama untuk menghindari konflik atau hasil yang tidak diharapkan. Saya melakukan itu untuk semua kolom dalam contoh saya.Tapi perhatikan konflik penamaan potensial antara
OUT
parametercnt
dan kolom alias dari nama yang sama. Dalam kasus khusus ini (RETURN QUERY SELECT ...
) Postgres menggunakan alias kolom di atasOUT
parameter dengan cara apa pun. Ini bisa jadi ambigu dalam konteks lain. Ada berbagai cara untuk menghindari kebingungan:ORDER BY 2 DESC
. Contoh:ORDER BY count(*)
.plpgsql.variable_conflict
atau gunakan perintah khusus#variable_conflict error | use_variable | use_column
dalam fungsi. Lihat:Jangan gunakan "teks" atau "hitung" sebagai nama kolom. Keduanya legal untuk digunakan di Postgres, tetapi "count" adalah kata yang dicadangkan dalam SQL standar dan nama fungsi dasar dan "teks" adalah tipe data dasar. Dapat menyebabkan kesalahan yang membingungkan. Saya menggunakan
txt
dancnt
dalam contoh saya.Menambahkan
;
kesalahan sintaks yang hilang dan mengoreksi di header.(_max_tokens int)
, bukan(int maxTokens)
- ketik setelah nama .Saat bekerja dengan pembagian bilangan bulat, lebih baik mengalikannya terlebih dahulu dan membagi nanti, untuk meminimalkan kesalahan pembulatan. Lebih baik lagi: bekerja dengan
numeric
(atau tipe floating point). Lihat di bawah.Alternatif
Menurut saya, seperti inilah tampilan kueri Anda (menghitung bagian relatif per token ):
Ekspresi tersebut
sum(t.cnt) OVER ()
adalah fungsi jendela . Anda dapat menggunakan CTE daripada subkueri - cantik, tetapi subkueri biasanya lebih murah dalam kasus sederhana seperti ini.Pernyataan eksplisit
RETURN
akhir tidak diperlukan (tetapi diizinkan) saat bekerja denganOUT
parameter atauRETURNS TABLE
(yang membuat penggunaanOUT
parameter secara implisit ).round()
dengan dua parameter hanya berfungsi untuknumeric
tipe.count()
di subquery menghasilkanbigint
hasil dansum()
over inibigint
menghasilkannumeric
hasil, sehingga kita menanganinumeric
nomor secara otomatis dan semuanya jatuh ke tempatnya.sumber
RETURN;
sebelum ituEND;
, setidaknya saya melakukannya - tapi saya melakukan UNION jadi saya tidak yakin apakah itu membuatnya berbeda.RETURN
. Memperbaiki kesalahan yang tidak terkait dan menambahkan beberapa perbaikan saat melakukannya.Hai, silakan periksa tautan di bawah ini
https://www.postgresql.org/docs/current/xfunc-sql.html
EX:
sumber