就我所知,我的函数与我所看到的示例非常相似。有人能告诉我如何让它工作吗?
create or replace function get_user_by_username(
username varchar(250),
online boolean
) returns setof record as $$
declare result record;
begin
if online then
update users
set last_activity = current_timestamp
where user_name = username;
end if;
return query
select
user_id,
user_name,
last_activity,
created,
email,
approved,
last_lockout,
last_login,
last_password_changed,
password_question,
comment
from
users
where
user_name = username
limit 1;
return;
end;
$$ language plpgsql;
3条答案
按热度按时间fcg9iug31#
返回所选列
电话:
你有
DECLARE result record;
,但没有使用变量。我删除了cruft。您可以直接从
UPDATE
传回记录,这比呼叫额外的SELECT
陈述式快得多。请使用RETURN QUERY
和UPDATE
with aRETURNING
clause。如果用户不是
_online
,则默认为普通的SELECT
。如果省略第二个参数,这也是(安全)默认值-只有在函数定义中为DEFAULT false
提供该默认值后,才可能省略第二个参数。如果在函数内部的查询中不对列名进行表限定(
tablename.columnname
),请注意列名和命名参数之间的命名冲突,这在函数内部的任何地方都是可见的(大多数情况下)。您也可以使用参数的位置参照(
$n
)来避免这种恩怨。或者使用您 * 从不 * 用于数据行名称的前置词:例如下划线(_username
)。如果**
users.username
在表中定义为unique**,则第二个查询中的LIMIT 1
只是cruft。如果它不是,则UPDATE
可以更新多行,这很可能是错误的。我假设username
是唯一的,并修剪噪声。定义函数的返回类型(如@ertx所示),或者必须为每个函数调用提供一个列定义列表,这是很尴尬的。
为此目的创建一个类型(像@ertx建议的那样)是一种有效的方法,但对于单个函数来说可能有些过头了。这是在我们有
RETURNS TABLE
之前旧版本Postgres的做法--就像上面演示的那样。对于这个简单的函数,您不需要循环。
每个函数都需要一个语言声明。在本例中为**
LANGUAGE plpgsql
**。我使用
timestamptz
(timestamp with time zone
)而不是timestamp
(timestamp without time zone
),这是一个正常的默认值。返回整行(一组)
要返回现有表
users
的 * 所有列 *,有一个更简单的方法。Postgres自动为每个表定义一个同名的复合类型。只需使用RETURNS SETOF users
就可以大大简化查询:返回整行加上自定义加法
为了解决TheRealChx 101在下面的评论中添加的问题:
如果除了整个表格之外,您还有一个计算值,该怎么办?😑
虽然不是那么简单,但也是可行的。我们可以将整个行类型作为 one 字段发送,然后添加更多:
“魔术”就在函数调用中,我们(可选地)分解行类型:
如果您需要更“动态”的东西,请考虑:
e3bfsja22#
如果希望创建返回setof记录函数,则需要在select语句中定义列类型,
More info
您的查询应如下所示:
(you可能需要更改数据类型)
我个人更喜欢类型方法。它确保了如果函数被编辑,所有的查询都将返回正确的结果。这可能是一个痛苦,因为每次你修改函数的参数,你都需要重新创建/删除类型。
例如:
dtcbnfnu3#
由于只返回一条记录(通过
LIMIT 1
),因此也可以删除SETOF
并声明如下函数:然后,从
SELECT
子句而不是FROM
子句引用该函数(如果您没有使用类型化记录,则仍然不可能这样做):结果如下所示: