如何插入 select 查询的结果(如果 return 没有行则默认)作为 Postgres 函数的一部分?

How to insert result of select query (with default if return no rows) as part of Postgres Function?

对于我的 Nextjs 网站,我将后端配置为在 auth.users table 中插入一行时自动将用户信息添加到 public.profiles table(通过 Supabase 的身份验证自动完成)。

我有一个 public.college_emails table,其中包含 1700 多所大学的名称以及与之关联的电子邮件标签。当用户使用他们的学校电子邮件创建帐户时,我希望它 return 与他们的电子邮件标签相关联的大学名称,并将其输入到他们的“学校”字段中。否则,如果他们使用的电子邮件不在我的列表中,它将插入“其他”。

我能够让 Supabase 编译我的 SQL 而没有语法错误,但是在尝试添加新用户时,它失败并出现错误 Database error when creating user。 (我发现这是在与用户创建相关的触发器或函数出现问题时。当我删除执行我之前提到的功能的代码时,它工作正常(但只是不正确select学院名称。

这是我的 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();

我的大学 table 格式为:

email (text): 'example@mycollege.edu'; college (text): 'My College'; tag (text): 'mycollege.edu'

这就是我现在的功能(恢复到工作版本以继续测试)。这缺少添加正确大学名称的代码。 table 和触发器保持不变:

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;

我的预期结果:

User with email "myname@uci.edi" registers and is added to auth.users. A new row is added to public.profiles with email: "myname@uci.edu", username: "myname", and school: "University of California Irvine"

像这样更新你的触发器函数 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;