В игре, использующей PostgreSQL 9.3 в качестве серверной части, я пытаюсь ограничить количество игр, в которые играет пользователь в неделю.
Я подготовил скрипт SQL, но, к сожалению, он не работает.
Мой (тестовый, а не производственный) код находится здесь:
create table pref_users (
id varchar(32) primary key,
last_ip inet
);
create table pref_match (
id varchar(32) references pref_users on delete cascade,
completed integer default 0 check (completed >= 0),
yw char(7) default to_char(current_timestamp, 'IYYY-IW'),
primary key(id, yw)
);
А вот хранимая процедура, с помощью которой я пытаюсь найти количество игр, сыгранных на этой неделе:
create or replace function pref_get_user_info(
IN _id varchar,
IN _last_ip inet,
OUT games_this_week integer
) as $BODY$
begin
select sum(completed)
into games_this_week
from pref_match where
(id = _id or
id in (select id from pref_users where last_ip=_last_ip)) and
yw=to_char(current_timestamp, 'IYYY-IW');
end;
$BODY$ language plpgsql;
С этим условием:
(id = _id or
id in (select id from pref_users where last_ip=_last_ip))
Я пытаюсь поймать пользователей, которые попытаются обмануть и присоединиться к игре с другим игроком id
, но с того же IP-адреса.
Но меня беспокоит, что иногда я получу удвоенное количество пройденных игр - потому что в вышеприведенном условии сначала совпадет 1-я часть: id = _id
а потом 2-я часть id in (...)
- и это даст мне количество игр в 2 раза.
Пожалуйста, есть ли какое-нибудь лекарство от этого?
Мне нужно «обнаружить», когда id
используется дважды в приведенном выше условии.
NOT NULL
кcompleted
? Развеdefault 0
недостаточно? 17.06.2014NOT NULL
. Стандартного значения недостаточно — таким образом можно ввести NULL. Также помогает хранение и планирование запросов. 18.06.2014