PostgreSQL:错误:42601:返回“记录”的函数需要列定义列表
据我所知,我的函数与我所看到的示例非常相似。有人能告诉我怎么做吗PostgreSQL:错误:42601:返回“记录”的函数需要列定义列表,postgresql,parameter-passing,plpgsql,set-returning-functions,Postgresql,Parameter Passing,Plpgsql,Set Returning Functions,据我所知,我的函数与我所看到的示例非常相似。有人能告诉我怎么做吗 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_a
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;
如果要创建函数返回记录集,则需要在select语句中定义列类型 您的查询应该如下所示:
select * from get_user_by_username('Username', True) as
f(user_id integer, user_name varchar, last_activity, varchar, created date, email archar, approved boolean, last_lockout timestamp, last_login timestamp,
last_password_changed timestamp, password_question varchar, comment varchar)
您可能需要更改数据类型
我个人更喜欢类型方法。它确保如果编辑函数,所有查询都将返回正确的结果。这可能是一种痛苦,因为每次修改函数的参数时,都需要重新创建/删除类型
例如:
返回所选列
创建或替换函数get_user_by_username_username text
,\u联机bool默认值为false
返回表
用户id int
,用户名varchar
,最后一项活动
语言plpgsql AS
$func$
开始
如果你在线的话
返回查询
更新用户u
设置最后\u活动=当前\u时间戳-带时区的ts
其中u.user\u name=\u username
正在返回u.user\u id
,u.user\u名称
最后一次活动;
其他的
返回查询
选择u.user\u id
,u.user\u名称
,u.last_活动
来自用户u
其中u.user\u name=\u username;
如果结束;
终止
$func$;
电话:
您已申报成绩记录;但是没有使用变量。我删除了积垢
您可以直接从更新返回记录,这比调用额外的SELECT语句快得多。使用返回查询和
如果用户不在线,则默认为普通选择。如果省略了第二个参数,这也是安全的默认值-只有在函数定义中使用default false提供该默认值后才可能
如果在函数内部的查询中没有对列名tablename.columnname进行表限定,请注意列名和命名参数之间的命名冲突,因为在函数中,列名和命名参数在任何地方都是可见的。
还可以通过对参数使用位置引用$n来避免此类冲突。或者使用从未用于列名的前缀:例如下划线\用户名
如果在表中定义的users.username是唯一的,那么第二个查询中的限制1就是错误的。如果不是,则更新可以更新多行,这很可能是错误的。我假设一个唯一的用户名,并消除噪音
定义像@ertx这样的函数的返回类型,或者必须为每个函数调用提供一个列定义列表,这很尴尬
为此目的创建一个类型(如@ertx)是一种有效的方法,但对于单个函数来说可能有些过分。这是我们之前在旧版本的博士后考试中所采用的方法,就像上面演示的那样
这个简单函数不需要循环
每个函数都需要一个语言声明。在本例中为plpgsql语言
我使用带时区的timestamp timestamp,而不是不带时区的timestamp timestamp timestamp,这是正常的默认值。见:
整行返回集
要返回现有表用户的所有列,有一种更简单的方法。Postgres会自动为每个表定义一个同名的复合类型。只需使用一组用户即可大大简化查询:
创建或替换函数get_user_by_username_username text
,\u联机bool默认值为false
返回一组用户
语言plpgsql AS
$func$
开始
如果你在线的话
返回查询
更新用户u
设置最后\u活动=当前\u时间戳
其中u.user\u name=\u username
返回u.*;
其他的
返回查询
挑选*
来自用户u
其中u.user\u name=\u username;
如果结束;
终止
$func$;
返回整行加上自定义添加
要解决ALCHX101在以下评论中添加的问题:
如果在整个表之外还有一个计算值呢?该示例如何定义列类型?在我看来,它只是插入行。返回查询不应该将结果发送回去吗?你能给我一个例子,我将如何改变我的功能,以满足要求?谢谢。。。我不知道为什么我所看到的任何文档中都没有显示。您也可以使用参数,这类工作类似于声明类型,但您不必管理单独的对象。如本文所述,您还可以定义一个自定义类型,并将其与json_populate_record结合使用,以在不使用plpgsql的情况下实现相同的功能—非常干净。Ertx把我带到了一个地方,在那里我可以找出剩下的,但这是一篇优秀的文章。我希望它能为其他PostgreSQL新手消除一些困惑。如果除了一个完整的表之外还有一个计算值呢@疗法
ealChx101:我添加了第三个解决方案来解决这个问题。谢谢。这很有帮助。你就像数据库里的耶稣一样。有时候我想知道你脑子里在想什么,哈哈哈。
CREATE TYPE return_type as
(user_id integer,
user_name varchar,
last_activity varchar,
created timestamp,
email varchar,
approved boolean,
last_lockout timestamp ,
last_login timestamp,
last_password_changed timestamp,
password_question varchar,
comment varchar);
create or replace function get_user_by_username( username varchar(250), online
boolean) returns setof return_type as $$
declare _rec return_type;
begin
if online then
update users
set last_activity = current_timestamp
where user_name = username;
end if;
for _rec in 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
loop
return next _rec;
end loop
end;
$$ language plpgsql;
SELECT * FROM get_user_by_username('myuser', true);