提问者:小点点

PostgreSQL中事务语句的函数


我希望通过用户的昵称(networkid)和之前的散列密码,使用用户公共表(recoyx.user)和用户私有表(recoyx_private.user)对用户进行身份验证。 该函数基于浏览这个PostGraphile教程(PostGraphile结合了GraphQL和PostgreSQL)。

create function recoyx.authenticate(
    network_id text,
    password_hash text
) returns recoyx.jwt_token
begin;
    set local id to (select (numeric_id) from recoyx.user where user.network_id = $1).numeric_id;
    select (numeric_id, password_hash)::recoyx.jwt_token
        from recoyx_private.user
        where user.numeric_id = id and user.password_hash = $2;
end;

查询运行程序在该函数中给出的语法总体上无效,包括select*from recoyx.table(其中table.field=value),事务帧和id绑定部分。 我从这个例子中获得了查询运行器,它提供了一个简短的工具,用于初始化,查询和释放PostgreSQL数据库的查询运行器(我是通过这个postgraphile模块API文档来到这里的)。

当我从查询中消除这个函数时,它运行得很好。 就我刚才所见,点是有效的,本地分配也是有效的。 那么我的语法真的错了吗?

这就是我的功能:

create function recoyx.authenticate(
    network_id text,
    password_hash text
) returns recoyx.jwt_token
as
$body$
    select (numeric_id, password_hash)::recoyx.jwt_token
        from recoyx_private.user
        where   numeric_id = (select numeric_id from recoyx.user where network_id = $1)
            and password_hash = $2;
$body$
language sql
stable;

我得到了未定义的关系,但在运行create function查询时,我连接到了PostgreSQL安装中的默认根角色(postgres角色

我已经把这个项目放到GitHub上了。 我正在通过npm run init-database运行查询。 请参见_exec.js(它传递默认的角色连接URI)。


共1个答案

匿名用户

正如手册中所描述的,函数体在Postgres中作为字符串传递(您链接到的教程实际上包含了必要的作为$$...$$-您只是没有复制它)。 您还忘记指定函数的语言。

set local id在PL/PGSQL和SQL中都不是有效的变量赋值(SQL一开始就没有变量)。

但是你并不真正需要一个变量来做你想做的事情,你的函数可以实现为一个SQL函数:

create function recoyx.authenticate(
    network_id text,
    password_hash text
) returns recoyx.jwt_token
as
$body$
  select (numeric_id, password_hash)::recoyx.jwt_token
  from recoyx_private.user
  where user.numeric_id = (select numeric_id 
                           from recoyx.user 
                           where network_id = $1)
    and user.password_hash = $2;
$body$
language sql
stable;