は、私は、ユーザーがVIP(「非常に重要な人物」)を購入することができる小型ゲーム、ステータスを持っているに:タイムスタンプの検証はnullであるかのPostgreSQL 8.4.9で過去
# \d pref_users;
Table "public.pref_users"
Column | Type | Modifiers
------------+-----------------------------+---------------
id | character varying(32) | not null
vip | timestamp without time zone |
vipがありませんでした場合購入した場合はNULLになります。
vipが期限切れの場合、< CURRENT_TIMESTAMPになります。
私は十分VIPステータスを持つユーザーは、「贈り物」として、他のユーザーにそれの週を与えるために残さできるようにPL/pgSQLのプロシージャを作成しようとしています:
create or replace function pref_move_week(_from varchar,
_to varchar) returns void as $BODY$
declare
has_vip boolean;
begin
select vip > current_timestamp + interval '1 week'
into has_vip from pref_users where id=_from;
if (not has_vip) then
return;
end if;
update pref_users set vip = current_timestamp - interval '1 week' where id=_from;
update pref_users set vip = current_timestamp + interval '1 week' where id=_to;
end;
$BODY$ language plpgsql;
残念ながら、この手順は動作しません。与えられたユーザのvipがNULLの場合、適切に:
# update pref_users set vip=null where id='DE16290';
UPDATE 1
# select id,vip from pref_users where id in ('DE16290', 'DE1');
id | vip
---------+----------------------------
DE1 | 2012-01-05 17:35:17.772043
DE16290 |
(2 rows)
# select pref_move_week('DE16290', 'DE1');
pref_move_week
----------------
(1 row)
# select id,vip from pref_users where id in ('DE16290', 'DE1');
id | vip
---------+----------------------------
DE1 | 2012-01-05 17:43:11.589922
DE16290 | 2011-12-22 17:43:11.589922
(2 rows)
IF - 上記の記述は機能しないと思われます。
ここでもhas_vip変数が必要なのでしょうか?
そして、どのように私は主キーが_fromと_toがpref_users表に本当に存在しているかUPDATE文の一つが「例外がスローされますので、(このすでに撮影したケアであることを確認できました"トランザクションはロールバックされます)。
UPDATE:
は、すべての返信をありがとう、私はまた、使用するヒントを持っている:
if (not coalesce(has_vip, false)) then
return;
end if;
しかし、今、私は新しい問題があります。
# select id,vip from pref_users where id in ('DE16290', 'DE1');
id | vip
---------+----------------------------
DE1 | 2012-01-05 17:43:11.589922
DE16290 |
(2 rows)
を
(すなわち、DE1は5月までVIPを持ち、DE16290に1週間与えることができるはずですが):
# select pref_move_week('DE1', 'DE16290');
pref_move_week
----------------
(1 row)
# select id,vip from pref_users where id in ('DE16290', 'DE1');
id | vip
---------+----------------------------
DE1 | 2012-01-05 17:43:11.589922
DE16290 |
(2 rows)
(いくつかの理由については何も変わっていない?)
UPDATE 2:最終的なソリューション -
create or replace function pref_move_week(_from varchar,
_to varchar) returns void as $BODY$
begin
select 1 from pref_users
where id=_from and
vip > current_timestamp + interval '1 week';
if not found then
return;
end if;
update pref_users set
vip = vip - interval '1 week'
where id=_from;
update pref_users set
vip = greatest(vip, current_timestamp) + interval '1 week'
where id=_to;
end;
$BODY$ language plpgsql;
ありがとうございます - はい、私はPerl、PHP、Java、Cの経験がありますが、SQLを使用する必要があるときはいつでも(私は基本的なselect/update/delete文のほかに)苦労しています。更新された質問のアドバイスをお願いしますか? –
私の答えを編集しました...私はその論理に従ったと仮定して、私はあなたがVIPがヌルであれば逃げることができると思います。ちょっと面白いこと(has_vipでない)が返すと思われるものについて私が混乱している場合。 – Twelfth
あなたの方法はより良いです、ありがとう –