只有在Postgresql中列不为null时,如何强制执行约束?

时间:2009-02-23 22:42:11

标签: postgresql constraints unique-key

我想要一个解决方案,只有在列不为空时才强制执行约束。我似乎无法在文档中找到这样做的方法。

create table mytable(
  table_identifier_a INTEGER,
  table_identifier_b INTEGER,
  table_value1,...)

对于数据的性质,我将在创建表时使用标识符b和值。在我们收到其他数据后,我将能够填充标识符a。此时我想确保unique key of (identifier_a, value1),但仅限于identifier_a存在。

希望这是有道理的,任何人都有任何想法?

5 个答案:

答案 0 :(得分:7)

嗯。唯一约束不会阻止多个NULL值。

CREATE TABLE mytable (
    table_identifier_a   INTEGER    NULL,
    table_identifier_b   INTEGER    NOT NULL,
    table_value1         INTEGER    NOT NULL,

    UNIQUE(table_identifier_a, table_identifier_b)
);

请注意,我们可以在其中插入多个NULL,即使在identifier_b时也是如此 符合条件:

test=# INSERT INTO mytable values(NULL, 1, 2);
INSERT 0 1
test=# INSERT INTO mytable values(NULL, 1, 2);
INSERT 0 1
test=# select * from mytable;
 table_identifier_a | table_identifier_b | table_value1 
--------------------+--------------------+--------------
                    |                  1 |            2
                    |                  1 |            2
(2 rows)

但是我们不能创建重复的(a,b)对:

test=# update mytable set table_identifier_a = 3;
ERROR:  duplicate key value violates unique constraint "mytable_table_identifier_a_key"

当然,您确实遇到了问题:您的表没有主键。您 可能有数据模型问题。但是你提供的不够 细节来解决这个问题。

答案 1 :(得分:1)

如果在一次交易中完成整个操作是可行的,则可以改变postgres评估约束的时间,即:

START;
SET CONSTRAINTS <...> DEFERRED;
<SOME INSERT/UPDATE/DELETE>
COMMIT;

在这种情况下,约束在commit时计算。看到: Postgres 7.4 Doc - Set constraintsPostgres 8.3 Doc

答案 2 :(得分:1)

实际上,我可能会把它分成两个表。你在模拟两种不同的东西。第一个是初始版本,它只是部分版本,第二个版本是整个版本。一旦将第一类东西带到第二类所需的信息,将行从一个表移动到另一个表。

答案 3 :(得分:0)

您可以使用触发器而不是约束来处理此问题。

答案 4 :(得分:0)

如果我是你,我会将表分成两个表,并可能创建根据需要组合它们的视图。