Shv*_*alb 3 sql postgresql plpgsql sql-update sql-returning
我是编写DB函数的新手,我需要OUT在执行UPDATE查询时返回'last_login_at'的值作为参数.
这是我的功能片段:
...
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;
Run Code Online (Sandbox Code Playgroud)
可以做多个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;
...
Run Code Online (Sandbox Code Playgroud)
唯一的问题是,在已经更新的那一点上RETURNING,last_login_at所以CASE总是返回TRUE.
我的问题有一个神奇的解决方案吗?
我的问题有一个神奇的解决方案吗?
实际上,有:连接到子句"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;Run Code Online (Sandbox Code Playgroud)
现在,表别名u是指表的后UPDATE状态,但是u1指的是查询开始时的快照.
详细说明:
表限定所有列引用都是明确的,这绝不是一个坏主意,但在自连接之后它是必需的.
您可以使用RETURNING子句中的任何表达式,包括CASE语句.恰好有一种更简单,更便宜的方式:
CASE WHEN date_part('day', age(current_timestamp, last_login_at)) = 0
THEN true ELSE false END
Run Code Online (Sandbox Code Playgroud)
步骤1:
CASE WHEN last_login_at < now() + interval '1 day'
THEN true ELSE false END
Run Code Online (Sandbox Code Playgroud)
第2步:
(last_login_at < now() + interval '1 day')
Run Code Online (Sandbox Code Playgroud)
只需使用boolean结果.如果last_login_at是NULL,你得到NULL.
旁白:
对于其余查询:表达式可以简化,该LOOP可疑,你应该永远不会使用保留字作为标识符,即使双引号能够(),该算法似乎取决于执行确切 24小时间隔,这是容易出错的."user"
| 归档时间: |
|
| 查看次数: |
3023 次 |
| 最近记录: |