PostgreSQL - 我有啥办法可以定义一个在插入或更新时将空字符串转换为 null 的列?
Posted
技术标签:
【中文标题】PostgreSQL - 我有啥办法可以定义一个在插入或更新时将空字符串转换为 null 的列?【英文标题】:PostgreSQL - Any way I can define a column that will cast empty string to null on insert or update?PostgreSQL - 我有什么办法可以定义一个在插入或更新时将空字符串转换为 null 的列? 【发布时间】:2021-12-29 20:28:28 【问题描述】:我正在使用 PostgreSQL 12。我有 'users' 表,其中 'email' 列可以为空表示可选列,但它具有预期的唯一约束。这个 'email' 列是 'citext' 类型的列。
问题是即使我将 'email' 值发送为 NULL,数据库在插入期间将其保存为空字符串而不是 NULL 在 'email' 列中。有什么方法可以在插入或更新时将“电子邮件”列的空字符串转换为 NULL?因为它有唯一约束,如果多个用户没有提供'email',它需要为NULL以避免唯一约束错误。
我正在使用 php Laravel 框架。没有定义mutator。控制器部分如下:
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”约束的东西,我们可以在列中定义自动转换?
提前致谢。
【问题讨论】:
数据库未将NULL
转换为空字符串,这是在客户端完成的。您需要提供有关您的客户端是什么以及如何创建查询并将查询发送到数据库的更多信息。
您可以有一个触发器来执行转换。 (并检查@等)
那么,无论$user
代表什么,它都在做某事。我不是PHP
程序员,所以其他人必须插话。
您需要一个触发器来模拟 Oracle 的行为
【参考方案1】:
不,正如@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 破坏和破坏的数据。
【讨论】:
【参考方案2】:你可以使用 NULLIF()
INSERT INTO your_table (cols..., email) VALUES (..., NULLIF(your_email, ''))
【讨论】:
非常感谢。是否有像“CHECK()”这样的约束我们可以更改和更改列定义?那么 PostgreSQL 会自动转换它吗? PostgreSQL 不会自动将空字符串转换为空字符串作为 oracle .. 如果您需要这个,您可以在插入或更新阶段使用触发器或管理转换...无论如何函数都是 NULLIF( )以上是关于PostgreSQL - 我有啥办法可以定义一个在插入或更新时将空字符串转换为 null 的列?的主要内容,如果未能解决你的问题,请参考以下文章
PostgreSQL 中 JSONB[] (JSONB ARRAY) 数据类型有啥用?
有没有办法在 PostgreSQL 查询中定义一个命名常量?
连接到 postgresql 时 -> 和 => 有啥区别?