我希望通过用户的昵称(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)。
正如手册中所描述的,函数体在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;