sql - Postgres : How to prevent INSERT in a special case

标签 sql database postgresql

我有一张表 'foo' 看起来像

   ID  | NAME 
 ------+----------------------------
   123 | PiratesAreCool
   254 | NinjasAreCoolerThanPirates

和第二个表'bar'

  SID  |  ID  |  created   |  dropped
 ------+------+------------+-----------
  9871 |  123 | 03.24.2009 | 03.26.2009
  9872 |  123 | 04.02.2009 | 

bar.ID 是对 foo.ID 的引用(外键)。

现在我想防止当存在具有相同 ID 的记录且 bar.dropped 在该记录上为 null 时,您可以将新记录插入“bar”。

因此,当“条形图”如上所示时

   INSERT INTO BAR VALUES ('9873','123','07.24.2009',NULL);

应该禁止,但是

   INSERT INTO BAR VALUES ('9873','254','07.24.2009',NULL);

应该被允许(因为没有“NinjasAreCoolerThanPirates”的“开放”条记录)。

我该怎么做? 我希望我的问题很清楚,有人可以帮助我。

最佳答案

嗯,这应该足以创建一个唯一索引。

create unique index ix_open_bar on bar (id, dropped);

当然,这也会产生这样的效果,即您不能每天两次删除一个条(除非删除的是一个可以将风险降至最低的时间戳)

实际上,我注意到 Postgres 支持部分索引:

 create unique index ix_open_bar on bar (id) where dropped is null;

更新: 经过一些测试,没有对空值强制执行唯一约束,但部分索引仍然有效。

如果您不想使用部分索引,这也可能有效:

 create unique index ix_open_bar on bar(id, coalesce(dropped, 'NULL'));

但是,当使用 coalesce 时,它​​们需要具有相同的数据类型(因此,如果 dropped 是时间戳,则需要将“NULL”更改为时间戳值)。

关于sql - Postgres : How to prevent INSERT in a special case,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1178057/

相关文章:

SQL Server 更改表查询(语法不正确)

c# - 带参数的 SqlCommand

mysql - 无法在搜索过滤器查询中找到所需的结果

sql - 需要找到两个日期之间的差异以及时间戳,但我需要在 postgresql 中排除星期六和星期日

javascript - 在应用层(使用 sequelize 或其他)如果已读取的数据(SELECT)已更改(UPDATE)则中止 SQL 事务

sql - 当我尝试插入小时数时,sql server 中的数据类型时间显示错误

mysql - 将表与其自身连接

android - 原始查询 : bind or column index out of range

PHP MongoDB 计数记录

postgresql - Postgres pg_dump 对生产数据库的影响