Saya memiliki daemon permainan non-forking yang ditulis dalam Perl , yang menggunakan kueri acync untuk menulis statistik pemain ke dalam database PostgreSQL 9.3. Tetapi ketika saya perlu membaca sesuatu dari basis data (seperti jika pemain dilarang atau jika pemain memiliki status VIP), maka saya menggunakan kueri sinkron.
Ini membuat game berhenti sejenak, hingga nilainya dibaca dari database.
Saya tidak bisa menulis ulang daemon gim saya untuk menggunakan kueri async untuk membaca nilai (saya sudah mencoba, tetapi itu membutuhkan terlalu banyak perubahan), jadi pertanyaan saya adalah : apakah masuk akal untuk menggabungkan beberapa kueri yang tidak terkait (yang perlu saya buat ketika pemain baru menghubungkan) ke 1 prosedur dan bagaimana saya bisa mengembalikan beberapa nilai pada saat yang sama ke program Perl saya?
Kueri saya saat ini semua menggunakan ID pemain sebagai parameter dan mengembalikan nilai 1:
-- Has the player been banned?
select true from pref_ban where id=?
-- What is the reputation of this player?
select
count(nullif(nice, false)) -
count(nullif(nice, true)) as rep
from pref_rep where id=?
-- Is he or she a special VIP player?
select vip > now() as vip from pref_users where id=?
-- How many games has the player played to the end?
select completed from pref_match where id=?
Untuk menggabungkan pertanyaan di atas, saya mungkin perlu prosedur seperti ini:
create or replace function get_user_info(_id varchar) returns XXX as $BODY$
declare
is_banned boolean;
reputation integer;
is_vip boolean;
completed_games integer;
begin
select 1 into is_banned from pref_ban where id=_id;
select
count(nullif(nice, false)) -
count(nullif(nice, true))
into reputation
from pref_rep where id=_id;
select vip > now() into is_vip from pref_users where id=_id;
select completed into completed_games from pref_match where id=_id;
return XXX; /* How to return 4 values here? */
end;
$BODY$ language plpgsql;
Tolong bantu saya untuk mendeklarasikan prosedur di atas dengan benar.
sumber
NULL
atauTRUE
di sayais_banned
variabel dengan pernyataan ini:select true into is_banned from pref_ban where id=_id
. Apakah ada cara untuk mengubahnya keFALSE
atauTRUE
?is_banned := exists(select 1 from pref_ban where id=_id)
harus bekerja, tapi itu pertanyaan yang berbeda.Anda harus mendefinisikan tipe komposit. Anda bisa menggunakannya sebagai tipe pengembalian fungsi dan untuk merekam variabel di dalam suatu fungsi.
Contoh:
Menurut pendapat saya menggunakan fungsi seperti ini cukup masuk akal baik dari segi kinerja dan logika aplikasi.
Jenis komposit yang ditentukan pengguna sangat berguna jika Anda ingin mengembalikan rangkaian baris dari fungsi Anda. Maka Anda harus mendefinisikan kembali jenis fungsi sebagai
setof composite-type
dan menggunakanreturn next
ataureturn query.
Contoh:
sumber
OUT
parameter pada dasarnya mencapai hal yang sama, tetapi tanpa membuat tipe yang ditentukan pengguna: postgresql.org/docs/current/static/…OUT
parameter - tetapi bagaimanaSELECT
mereka dalam kasus saya dari 4 kueri yang tidak terkait?drop type if exists user_type cascade; create type user_type as(...);
karena skrip Perl saya memanggil pernyataan SQL setiap kali saat start up.