1

4つの列に基づいてテーブルに制限を作成する必要があり、そのうちの2つは相互に排他的です。つまり、一方がNULLの場合、もう一方はそうではありません。

理想的なスクリプトは次のとおりです。

ALTER TABLE ONLY t_users_prizes
ADD CONSTRAINT t_user_prize_test_circuit_key
UNIQUE (id_event||':'||id_circuit, id_prize, id_user);

しかし、Postgresはこの種の連結を許可していません。

この制限をどのように実装できますか?

4

1 に答える 1

9

NULL値は制約に違反しません-2UNIQUENULLは等しいとは見なされません!したがって、単純なUNIQUE制約は機能しません。

2つの部分UNIQUEインデックスCHECK制約を使用してそれを実行できます。

CREATE TEMP TABLE foo (
  a int
, b int
, c int NOT NULL
, d int NOT NULL
, CHECK ((a IS NOT NULL AND b IS NULL) OR (b IS NOT NULL AND a IS NULL))
);

CREATE UNIQUE INDEX foo_acd_idx ON foo(a,c,d)
WHERE b is NULL;

CREATE UNIQUE INDEX foo_bcd_idx ON foo(b,c,d)
WHERE a is NULL;

INSERT INTO foo VALUES (NULL,2,3,4);
INSERT INTO foo VALUES (NULL,2,3,4);  -- error! 

私は、さらなる合併症を防ぐために、として宣言cしました。dNOT NULL

見る:

(1, NULL, 3, 4)とを禁止するには、代わりに(NULL, 1, 3, 4)1つのインデックスを使用できます。COALESCE

CREATE UNIQUE INDEX foo_xcd_idx ON foo(COALESCE(a,b),c,d);
于 2013-01-19T12:01:52.333 に答える