PostgreSQL - 我可以通过任何方式定义一个在插入或更新时将空字符串转换为 null 的列吗?

PostgreSQL - Any way I can define a column that will cast empty string to null on insert or update?

我正在使用 PostgreSQL 12。我有 'users' table 其中 'email' 列可为空意味着可选列,但它具有预期的唯一约束。此 'email' 列是 'citext' 类型的列。

问题是即使我将 'email' 值作为 NULL 发送,数据库在插入期间将其保存为空字符串而不是 'email' 列中的 NULL。有什么方法可以在插入或更新时将 'email' 列的空字符串转换为 NULL 吗?因为它有唯一约束,如果多个用户没有提供'email',它需要为NULL,以避免唯一约束错误。

我正在使用 PHP Laravel 框架。没有定义增变器。控制器部分如下:

    var_dump($user->email); // email is null still

    $success = $user->save(); // save DB changes by ORM

    var_dump($user->email); // is '' string now, NULL expected

我希望转换应该在后台发生,或者在插入或更新期间由 PostgreSQL 本身自动发生。可能类似于 'CHECK' 约束,我们可以在其中定义自动转换的列?

提前致谢。

你可以使用 NULLIF()

INSERT INTO your_table (cols..., email) VALUES (..., NULLIF(your_email, ''))

不,正如@a_horse_with_no_name 指出的那样,检查约束无济于事。这是一个触发器定义,应该可以解决您的问题。

create or replace function emailfix_tf()
returns trigger language plpgsql as
$$
begin
  new.email := nullif(trim(new.email), '');
  return new;
end;
$$;

create trigger users_emailfix_t
before insert or update on users
for each row execute procedure emailfix_tf();

无论如何,遗憾的是您必须定义一个触发器来修复被您的 ORM 损坏和损坏的数据。