0

我有用户表和配置文件表。当在 user 表中创建记录时,它会自动在 profile 表中使用返回的 id 创建一条记录。配置文件表如下:

create table app_public.profiles (
  user_id int not null primary key references users,
  first_name       text check (char_length(first_name) < 50),
  last_name        text check (char_length(last_name) < 50),
  display_name text
);

当用户更新配置文件表并为 和 输入值时first_namelast_name我想要一个触发器函数来连接两列并使用结果进行更新display_name

目前我将触发功能定义为

create function app_public.tg_user_display_name() returns trigger as $$
begin
  NEW.display_name = CONCAT(profiles.first_name || ' ' || NEW.profiles.last_name);
  return NEW;
end;
$$ language plpgsql volatile set search_path from current;

我也有触发器

create trigger _500_update_display_name
  before update on app_public.profiles
  for each row
  execute procedure app_public.tg_user_display_name();
4

2 回答 2

1

有一个更简单的方法。而不是创建一个检查约束来强制执行大小检查只是对定义施加了限制。此外,处理任一名称的 NULL 的最佳方法是不允许它。所以将 Profiles 定义为:

create table  profiles (
   user_id      integer     not null primary key  
 , first_name   varchar(49) not null
 , last_name    varchar(49) not null 
 , display_name text  
); 

如果您有更新的 Postgres 版本(v12 或更高版本),您可以完全消除触发器功能和触发器。定义display_name生成的列。然后就忘了它,除了选择那里你什么都不做。

create table  profiles (
   user_id      integer     not null primary key  
 , first_name   varchar(49) not null
 , last_name    varchar(49) not null 
 , display_name text generated always as (first_name || ' ' || last_name) stored 
);

请参阅以下示例中的差异:

带触发器的配置文件。注意:这将要求触发器在 Insert 和 Update 上触发。否则,更新将按照您的指示执行。

带有生成列的配置文件。注意:插入和更新将执行您等待的操作。

于 2021-08-17T23:28:09.567 回答
0

目前尚不清楚出了什么问题。你的跳跳虎功能看起来不错。一个小问题是将CONCAT()函数与字符串连接运算符一起使用。

SELECT 'Jon' || ' ' || 'Dir', concat('Jon' , ' ' , 'Dir')

使用 RAISE NOTICE 或 RAISE EXCEPTION 进行调试。

于 2021-08-17T19:22:55.630 回答