【问题标题】:How can I concat two strings to update a column in a postgres table using trigger function如何使用触发器函数连接两个字符串以更新 postgres 表中的列
【发布时间】:2021-10-19 14:17:54
【问题描述】:

我有用户表和个人资料表。当在 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();

【问题讨论】:

  • 1) 为什么要这样做?只需在查询表时执行此操作。 2) 如果你想这样做,那么它是NEW.first_nameNEW.last_nameNEW 仅将触发器所在的表的值保存为NEW.&lt;column_name&gt;
  • 如果答案解决了您的问题,请接受。接受答案有助于后来的提问者遇到同样的问题。此外,它会从未回答的队列中删除问题。如果没有一个足以解决您的问题,请发布剩下的内容。
  • 我已经接受了下面的第二个答案

标签: sql postgresql triggers string-concatenation postgresql-triggers


【解决方案1】:

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

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

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

【讨论】:

    【解决方案2】:

    有一个更简单的方法。而不是创建一个检查约束来强制执行大小检查只是对定义施加了限制。此外,处理任一名称的 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 定义为generated column。然后就忘了它,除了选择那里你什么都不用做。

    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 
    );
    

    查看以下示例的区别:

    Profile with Trigger。注意:这将要求触发器在 Insert 和 Update 上触发。否则,更新将按照您的指示执行。

    Profile with Generated Column。注意:插入和更新将执行您等待的操作。

    【讨论】:

    • 生成列的第二种方法非常适合我的用例。我在我的 Graphql 查询中对其进行了测试,结果非常完美。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-12-16
    • 1970-01-01
    • 1970-01-01
    • 2017-11-10
    • 2014-03-16
    • 2018-11-14
    • 1970-01-01
    相关资源
    最近更新 更多