Mam demona gry bez rozwidlania napisanego w Perlu , który używa zapytań acync do zapisywania statystyk graczy w bazie danych PostgreSQL 9.3. Ale kiedy muszę przeczytać coś z bazy danych (np. Jeśli gracz zostanie zbanowany lub jeśli ma status VIP), korzystam z zapytań synchronicznych.
To powoduje, że gra zatrzymuje się na chwilę, dopóki wartość nie zostanie odczytana z bazy danych.
Nie mogę przepisać mojego demona gry, aby używał zapytań asynchronicznych do odczytu wartości (próbowałem, ale wymagało to zbyt wielu zmian), więc moje pytanie brzmi : czy warto połączyć kilka niepowiązanych zapytań (które muszę zadać, gdy nowy gracz łączy) do 1 procedury i jak mogę zwrócić kilka wartości jednocześnie do mojego programu Perl?
Moje bieżące zapytania przyjmują identyfikator odtwarzacza jako parametr i zwracają 1 wartość:
-- 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=?
Aby połączyć powyższe zapytania, prawdopodobnie potrzebuję takiej procedury:
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;
Pomóż mi poprawnie zadeklarować powyższą procedurę.
źródło
NULL
czyTRUE
w moimis_banned
zmiennej z tym stwierdzeniemselect true into is_banned from pref_ban where id=_id
. Czy istnieje sposób, aby to zmienić naFALSE
lubTRUE
?is_banned := exists(select 1 from pref_ban where id=_id)
powinno działać, ale to inne pytanie.Powinieneś zdefiniować typ złożony. Można go użyć jako typu zwracanego funkcji i do rejestrowania zmiennych wewnątrz funkcji.
Przykład:
Moim zdaniem używanie takich funkcji jest dość rozsądne zarówno pod względem wydajności, jak i logiki aplikacji.
Zdefiniowane przez użytkownika typy złożone są bardzo przydatne, jeśli chcesz zwrócić zestaw wierszy z funkcji. Następnie powinieneś zdefiniować typ zwracanej funkcji jako
setof composite-type
i użyjreturn next
lubreturn query.
Przykład:
źródło
OUT
parametrów osiągnij w zasadzie to samo, ale bez tworzenia typów zdefiniowanych przez użytkownika: postgresql.org/docs/current/static/…OUT
parametrów - ale jakSELECT
w przypadku 4 niepowiązanych zapytań?drop type if exists user_type cascade; create type user_type as(...);
ponieważ mój skrypt Perla wywołuje instrukcje SQL za każdym razem podczas uruchamiania.