如何插入选择查询的结果(如果不返回任何行则默认)作为 Postgres 函数的一部分?
Posted
技术标签:
【中文标题】如何插入选择查询的结果(如果不返回任何行则默认)作为 Postgres 函数的一部分?【英文标题】:How to insert result of select query (with default if return no rows) as part of Postgres Function? 【发布时间】:2022-01-04 05:18:26 【问题描述】:对于我的 Nextjs 网站,我将后端配置为在向 auth.users 表中插入一行时自动将用户信息添加到 public.profiles 表中(通过 Supabase 的身份验证自动完成)。
我有一个 public.college_emails 表,其中包含 1700 多所大学的名称以及与它们关联的电子邮件标签。当用户使用他们的学校电子邮件创建帐户时,我希望它返回与他们的电子邮件标签关联的大学名称,并将其输入到他们的“学校”字段中。否则,如果他们使用不在我列表中的电子邮件,它将插入“其他”。
我能够让 Supbase 编译我的 SQL 而没有语法错误,但是在尝试添加新用户时,它失败并出现错误 Database error when creating user
。 (我发现这是当与用户创建相关的触发器或函数出现问题时。当我删除执行前面提到的功能的代码时,它工作正常(但只是没有正确选择大学名称。
这是我的 PostgreSQL 代码,它不起作用。它没有报告语法错误,但在尝试插入用户时失败:
create table if not exists public.profiles (
id uuid not null primary key, -- UUID from auth.users
email text,
full_name text,
avatar_url text,
created_at timestamp with time zone
);
create or replace function public.handle_new_user()
returns trigger as $$
begin
insert into public.profiles (id, email, full_name, school, created_at)
values (new.id, new.email, SPLIT_PART(new.email, '@', 1),
(SELECT coalesce(college, 'Other') FROM college_emails WHERE tag = SPLIT_PART(new.email, '@', 2)) // THIS LINE DOES NOT WORK
,current_timestamp);
return new;
end;
$$ language plpgsql security definer;
create trigger on_new_user_created
after insert on auth.users
for each row execute procedure public.handle_new_user();
我的大学表格格式为:
email (text): 'example@mycollege.edu'; college (text): 'My College'; tag (text): 'mycollege.edu'
这就是我现在的功能(恢复为工作版本以继续测试)。这缺少添加正确大学名称的代码。表和触发器保持不变:
create or replace function public.handle_new_user()
returns trigger as $$
begin
insert into public.profiles (id, email, full_name, school, created_at)
values (new.id, new.email, SPLIT_PART(new.email, '@', 1), SPLIT_PART(SPLIT_PART(new.email, '@', 2), '.', 1)
,current_timestamp);
return new;
end;
$$ language plpgsql security definer;
我的预期结果:
使用电子邮件“myname@uci.edi”的用户注册并添加到 auth.users。 向 public.profiles 添加了一个新行,其中包含电子邮件:“myname@uci.edu”、用户名:“myname”和
school: "University of California Irvine"
【问题讨论】:
【参考方案1】:像这样更新你的触发函数public.handle_new_user()
:
create or replace function public.handle_new_user()
returns trigger as $$
declare
coll text ;
begin
SELECT college
INTO coll
FROM college_emails
WHERE tag = SPLIT_PART(new.email, '@', 2);
IF NOT FOUND
THEN coll = 'Other' ;
END IF ;
INSERT INTO public.profiles (id, email, full_name, school, created_at)
SELECT new.id, new.email, SPLIT_PART(new.email, '@', 1), coll, current_timestamp ;
return new;
end;
$$ language plpgsql security definer;
【讨论】:
目前好像不行,我尝试用学校邮箱注册,还是收到Database error saving new user
当new.email对应表college_emails中的一个标签时,触发函数工作得很好,但是当它不对应时,查询中没有选择行,所以没有行插入到表public中。配置文件。我已经相应地更新了答案并对其进行了测试here。尝试直接从 sql 客户端进行测试。
虽然我仍然收到错误,但我能够将错误隔离到 supbase 的 组件;通过插入语句直接将用户添加到 auth.users (例如您的示例)正确地添加了找到的大学的新个人资料。我会接受您的回答并在单独的问题中提出新问题,谢谢!以上是关于如何插入选择查询的结果(如果不返回任何行则默认)作为 Postgres 函数的一部分?的主要内容,如果未能解决你的问题,请参考以下文章