【问题标题】:Unique constraint with null value interpreted as any value具有空值的唯一约束被解释为任何值
【发布时间】:2018-10-26 09:57:26
【问题描述】:

考虑表格

CREATE TABLE foo
(
    id uuid NOT NULL DEFAULT uuid_generate_v4(),
    col1 integer NOT NULL,
    col2 integer NOT NULL,
    col3 integer
)

我需要检查(col1, col2, col3) 的唯一性,col3 中的 NULL 表示任何值。也就是说,如果表中有一行(1, 2, NULL),那么将不可能插入一行有col1 = 1col2 = 2col3中的任何值(包括NULL)的行。反之,如果表中至少有一行col1 = 1col2 = 2col3中有一些非NULL值,则不能插入一行(1, 2, NULL),而是插入col1 = 1col2 = 2的行col3 中的任何值(NULL 除外)都将有效。

例如,这些值是有效的(第一个 id 列被省略):

(1, 2, 3)
(1, 2, 4)
(1, 2, 5)

(1, 2, NULL)
(1, 3, NULL)

但是这些值是无效的:

(1, 2, NULL)
(1, 2, 3)
(1, 2, 4)

(1, 2, NULL)
(1, 2, NULL)
(1, 2, 3)
(1, 2, 4)

我可以通过 PostgreSQL 做到这一点吗?我使用的是 9.6.5 版本。

【问题讨论】:

  • 这实际上是不可能的,因为您假设对插件进行排序。您可以同时插入多行,因此如果存在NULL 冲突,则不清楚使用哪个版本的规则。
  • 所以,基本上你想把 NULL 当作一个值。您可以使用标记值(例如 -1)并使 col3 不可为 NULL,也可以使用 (col1,col2,COALESCE(col3, -1)) 表达式来构造索引。
  • @joop 实际上没有。我想将 NULL 视为不是特定的值,而是任何可能的值。因此,不幸的是,您的方法无效 - 请参阅我帖子中无效值的第一个示例。

标签: sql postgresql unique-constraint


【解决方案1】:

在插入之前检查是否有一行:

col1=your_col1_value 
col2=your_col2_value
col3=null 

如果是这样,请不要插入您的行。

使用插入选择:https://www.postgresql.org/docs/current/static/sql-insert.html

而且不存在:https://www.postgresql.org/docs/current/static/functions-subquery.html

【讨论】:

  • 我猜你的意思是触发器,但我找到了一些基于索引的解决方案(对不起,如果我没有在问题中说明)。
猜你喜欢
  • 1970-01-01
  • 2021-09-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-06
  • 1970-01-01
相关资源
最近更新 更多