sql - 使表中的两列唯一
问题描述
我有一个看起来像这样的表:
ID | 电子邮件 | alt_email |
---|---|---|
1 | abc@gmail.com | 123@gmail.com |
2 | def@gmail.com | ghi@gmail.com |
每个用户都有一个电子邮件和备用电子邮件。我想让它在添加(或修改)用户时,PSQL 表不允许重复,即使在两列之间也是如此。例如,这是不允许的:
ID | 电子邮件 | alt_email |
---|---|---|
1 | abc@gmail.com | def@gmail.com |
2 | def@gmail.com | ghi@gmail.com |
因为def@gmail.com
是重复的。我怎样才能做到这一点?
解决方案
最简单的选择 - 不改变数据模型 - 将是在触发函数中控制它:
将列独立声明为UNIQUE
,以便在同一列中没有重复的电子邮件:
CREATE TABLE t (
id int,
email text UNIQUE,
alt_email text UNIQUE
);
创建一个函数来检查电子邮件是否存在于另一列中:
CREATE OR REPLACE FUNCTION check_email()
RETURNS TRIGGER AS $$
BEGIN
IF (SELECT EXISTS
(SELECT 1 FROM t WHERE alt_email = NEW.email OR email = NEW.alt_email)) THEN
RAISE EXCEPTION 'E-mail already exists!';
ELSE
RETURN NEW;
END IF;
END; $$ LANGUAGE plpgsql;
最后将触发器函数附加到表中
CREATE TRIGGER tgr_check_email
BEFORE INSERT OR UPDATE ON t
FOR EACH ROW EXECUTE PROCEDURE check_email();
演示:db<>fiddle
推荐阅读
- awk - 将类似 GenBank 的多行记录转换为新的文件格式(fasta 格式)
- javascript - JavaScript 异步性和运行时
- html - 为什么通过beautifulsoup导入的html和实际的html不一样?
- javascript - 在 Codepen 中使用 React 但没有得到任何东西
- c++ - 如何序列化/反序列化 std::map
C ++中的到/从json - complexity-theory - 计算复杂性:对大多数决策问题无法计算的证明中的矛盾感到困惑
- dax - 使用 dax 转换为正确的大小写
- loops - (AHK) 如何点击 X 次,等待,然后重复
- bash - Bash 脚本不应该执行一次
- css - 如何将最大宽度大于 100% 的 iframe 居中对齐以裁剪一些 iframe 宽度?