在PostgreSQL 9.3中,我有一个带有2个时间戳的表:
create table pref_users (
id varchar(32) primary key,
first_name varchar(64) not null,
last_name varchar(64),
female boolean,
avatar varchar(128),
city varchar(64),
mobile varchar(64),
login timestamp default current_timestamp,
logout timestamp,
last_ip inet,
vip timestamp, /* XXX can be NULL */
grand timestamp, /* XXX can be NULL */
mail varchar(256),
green integer,
red integer,
medals integer not null default 0
);时间戳vip和grand表示我的游戏用户是否支付了一定的特权--直到这些日期。
当用户连接到我的游戏服务器时,我使用OUT参数调用以下过程:
create or replace function pref_get_user_info(
IN _id varchar,
OUT is_banned boolean,
OUT is_grand boolean,
OUT is_vip boolean,
OUT rep integer
) as $BODY$
begin
is_banned := exists(select 1 from pref_ban where id=_id);
if is_banned then
return;
end if;
select
grand > current_timestamp,
vip > current_timestamp,
into is_grand is_vip
from pref_users where id=_id;
if is_grand or is_vip then
return;
end if;
select
count(nullif(nice, false)) -
count(nullif(nice, true))
into rep
from pref_rep where id=_id;
end;
$BODY$ language plpgsql;这确实很好,但有时会将NULL值传递给我的游戏守护进程(到Perl脚本):
# select * from pref_get_user_info('OK674418426646');
is_banned | is_grand | is_vip | rep
-----------+----------+--------+-----
f | | | 126
(1 row)不过,我不需要一个NULL (它在我的Perl脚本中打印一个警告)--我只需要一个"true“或"false”值。
所以我试过:
select
coalesce(grand, 0) > current_timestamp,
coalesce(vip, 0) > current_timestamp,
into is_grand is_vip
from pref_users where id=_id;但这给我带来了错误:
# select * from pref_get_user_info('OK674418426646');
ERROR: COALESCE types timestamp without time zone and integer cannot be matched
LINE 2: coalesce(grand, 0) > current_timesta...
^
QUERY: select
coalesce(grand, 0) > current_timestamp,
coalesce(vip, 0) > current_timestamp,
is_vip
from pref_users where id=_id
CONTEXT: PL/pgSQL function pref_get_user_info(character varying) line 9 at SQL statement所以我想知道这里该怎么做?
我真的必须
select
coalesce(grand, current_timestamp - interval '1 day') > current_timestamp,
coalesce(vip, current_timestamp - interval '1 day') > current_timestamp,
into is_grand is_vip
from pref_users where id=_id;或者有更好的方法(比如“时代开始”或“昨天”)?
更新:
正如Clodoaldo Neto所建议的(谢谢!)我试过:
select
coalesce(grand > current_timestamp, false),
coalesce(vip > current_timestamp, false),
into is_grand is_vip
from pref_users where id=_id;但是,当is_vip为空时,vip为空:
# select * from pref_get_user_info('OK674418426646');
is_banned | is_grand | is_vip | rep
-----------+----------+--------+-----
f | t | |
(1 row)当我尝试以下任何一种时,都会出现语法错误:
select
coalesce(grand > current_timestamp, false),
coalesce(vip > current_timestamp, false),
into is_grand, is_vip
from pref_users where id=_id;
select
coalesce(grand > current_timestamp, false),
coalesce(vip > current_timestamp, false),
into (is_grand, is_vip)
from pref_users where id=_id;如何在这里一次将两个变量SELECT成两个变量?
发布于 2014-06-19 16:42:13
如果您想要布尔值:
coalesce(grand > current_timestamp, false)如果您需要0或1:
coalesce((grand > current_timestamp)::integer, 0)在更新的问题中,选择列表和into子句之间有一个额外的逗号。
coalesce(vip > current_timestamp, false),
into is_grand, is_vip把它拿出来
coalesce(vip > current_timestamp, false)
into is_grand, is_viphttps://stackoverflow.com/questions/24311798
复制相似问题