我是编写数据库函数的新手,我需要在执行OUT
查询时将'last_login_at'的值作为UPDATE
参数返回。
以下是我的功能片段:
...
LOOP
UPDATE "user" SET
last_login_at = current_timestamp,
first_name = p_first_name,
last_name = p_last_name,
WHERE ext_user_id = p_ext_user_id AND platform_id = p_platform_id
RETURNING id INTO v_user_id;
is_new := false;
// The next 'CASE' is not valid - Need to replace it with a valid one.
has_logged_in_today = CASE
WHEN date_part('day', age(current_timestamp, last_login_at)) > 1
THEN true
ELSE false
END;
IF FOUND THEN
EXIT;
END IF;
..
..
END LOOP;
是否可以执行多个RETURNING x INTO y
?
我们可以在CASE
中使用RETURNING x INTO y
语句吗?
我能够获得更好的结果,现在看起来像这样:
...
LOOP
UPDATE "user" SET
login_consecutive_days = CASE
WHEN date_part('day', age(current_timestamp, last_login_at)) > 1
THEN 0
ELSE login_consecutive_days + date_part('day', age(current_timestamp, last_login_at))
END,
login_max_consecutive_days = CASE
WHEN date_part('day', age(current_timestamp, last_login_at)) = 1
AND (login_consecutive_days+1 > login_max_consecutive_days)
THEN login_consecutive_days+1
ELSE login_max_consecutive_days
END,
last_login_at = current_timestamp,
num_sessions = num_sessions + 1,
last_update_source = 'L',
first_name = p_first_name,
last_name = p_last_name,
additional_data = p_additional_data
WHERE ext_user_id = p_ext_user_id AND platform_id = p_platform_id
RETURNING id,
CASE
WHEN date_part('day', age(current_timestamp, last_login_at)) = 0
THEN true
ELSE false
END
INTO v_user_id, is_first_login_today;
is_new := false;
IF FOUND THEN
EXIT;
END IF;
...
唯一的问题是RETURNING
last_login_at
CASE
已经更新,因此TRUE
始终会返回while ($row = mysql_fetch_array($result))
{
$arr = explode('/', $row['filePath']);
$var[] = $arr[count($arr) -1];
}
。
我的问题是否有神奇的解决方案?
答案 0 :(得分:5)
我的问题是否有神奇的解决方案?
实际上,有:加入"user"
子句中FROM
表的另一个实例:
UPDATE "user" u
SET login_consecutive_days = ... -- unqualified column name
FROM "user" u1
WHERE u.ext_user_id = p_ext_user_id
AND u.platform_id = p_platform_id
AND u.id = u1.id -- must be unique not null (like the PK)
RETURNING u.id, (u1.last_login_at < now() + interval '1 day')
INTO v_user_id, is_first_login_today;
is_new := false;
EXIT WHEN FOUND;
现在,表别名u
引用了表的UPDATE
后状态,但u1
引用了查询开头的快照。
详细说明:
表格 - 所有列引用都是明确的,这绝不是一个坏主意,但在自我加入之后它是必需的。
The manual about the short syntax EXIT WHEN FOUND
.
您可以使用RETURNING
子句中的任何表达式,包括CASE
语句。恰好有一种更简单,更便宜的方式:
CASE WHEN date_part('day', age(current_timestamp, last_login_at)) = 0
THEN true ELSE false END
第1步:
CASE WHEN last_login_at < now() + interval '1 day'
THEN true ELSE false END
第2步:
(last_login_at < now() + interval '1 day')
只需使用boolean
结果即可。如果last_login_at
为NULL
,则会获得NULL
。
旁白:
至于查询的其余部分:表达式可以简化,LOOP
是可疑的,你应该从不使用reserved words作为标识符,即使双引号使其成为可能( ),算法似乎依赖于以精确 24h的间隔执行,这很容易出错。"user"
答案 1 :(得分:1)
您可以使用以下语法返回多个列:
UPDATE "user" SET
last_login_at = current_timestamp,
first_name = p_first_name,
last_name = p_last_name,
WHERE ext_user_id = p_ext_user_id AND platform_id = p_platform_id
RETURNING id, last_login_at
INTO v_user_id, v_login_at;
returns子句遵循SELECT字段列表的大多数规则,因此您可以根据需要添加任意数量的列。