回答

收藏

如何强制多个唯一集(列组合)在SQLite中互斥?

技术问答 技术问答 330 人阅读 | 0 人回复 | 2023-09-11

考虑一个包含可空列abc,def和xyz的表。如何执行:
  F8 M" x2 K, s[ol]如果’abc’不为null,则将1(’abc’)设置为UNIQUE,并且
' U! W( j$ q. y/ ?如果’def’和’xyz’都不为null,则将2(’def,xyz’)设置为UNIQUE,并且
7 a/ y, u) i: _, L% f; ^  Y上述集合中只有一个有效(包含非null)。
4 Z5 }4 K; `8 O3 _[/ol]
. ~; J7 ?4 z* w9 E. T# Y这是我尝试过的代码:
' Q) O6 {2 k! V6 U+ _4 R--# sqlite3 --version
& J" \6 t  Y# v--  3.13.0 ....* {# j7 g: l( q8 w' h( V$ b1 r
DROP TABLE IF EXISTS try;, i: L0 T  Z0 K  }0 }- ~
CREATE TABLE try(
, ?$ N+ J7 {' ~( p" o    -- 'abc' should be null,                  when 'def' and 'xyz' are not null.
9 `2 Z" s9 r; Z: q    -- 'abc' should be not be null,           when 'def' and 'xyz' are null.
1 \$ S7 ^% p8 A+ M2 m    -- 'def' and 'xyz' should be null,        when 'abc' is not null.9 i3 x- U: V, A1 G0 L
    -- 'def' and 'xyz' should be not be null, when 'abc' is null.: |0 b/ x+ p5 K4 K3 \- C* F$ {: K
    abc  TEXT,7 C. i1 x, ?( ?6 c$ p# o, o- R0 s
    def  TEXT,; e0 w, |$ S* Q$ @; R+ g+ [
    xyz  TEXT,
. _: K: b0 p2 ~9 Q% M    CONSTRAINT combo_1 UNIQUE(abc),8 B* A$ H" V9 q% a5 ^
    CONSTRAINT combo_2 UNIQUE(def, xyz)
; M3 \, H& k& j! A& U);
9 y1 m* D0 N1 k, zINSERT into try(abc)            VALUES("a1");              -- should succeed$ ~0 x8 c1 a# |% h. B- p
INSERT into try(def, xyz)       VALUES("d2", "x2");        -- should succeed
/ L, p& @' u  m1 R--! G) ?6 T/ i! c+ y& M/ ]
INSERT into try(abc)            VALUES(null);              -- should not be allowed1 [4 V+ s$ G5 Q' E
INSERT into try(abc, def)       VALUES("a4", "d4");        -- should not be allowed
1 V* i  U% g$ D  _% }; \INSERT into try(abc, xyz)       VALUES("a5", "x5");        -- should not be allowed. F4 I) Z( O* u' d" z9 {
INSERT into try(abc, def, xyz)  VALUES("a6", "d6", "x6");  -- should not be allowed1 s5 q2 v5 M8 ]: i
--
/ R- U- T& C+ @% n$ a2 E6 R0 BINSERT into try(def)            VALUES(null);              -- should not be allowed8 R; O. F, G# ^8 F* |( g4 p
INSERT into try(def)            VALUES("d8");              -- should not be allowed% d2 O: V/ M3 \1 \: g
--' Z. @" x# C+ y& M, N" W
INSERT into try(xyz)            VALUES(null);              -- should not be allowed! R! J2 }& X4 f; T
INSERT into try(xyz)            VALUES("x10");             -- should not be allowed
2 c1 i) }# Q, t* S7 N- ]--1 \0 G2 K0 [# K: j2 H4 j9 m$ [
INSERT into try(def, xyz)       VALUES(null, null);        -- should not be allowed+ e" O* }- n8 j+ ]0 R( W9 o
INSERT into try(def, xyz)       VALUES("d12", null);       -- should not be allowed
: `5 X0 G! \1 c; C: oINSERT into try(def, xyz)       VALUES(null, "x13");       -- should not be allowed
( [9 R/ z# @1 Z2 j, z% gINSERT into try(abc, def, xyz)  VALUES(null, null, null);  -- should not be allowed8 |& h* g6 t' l% s
.headers ON
: \9 r% @& @1 g$ k; dselect rowid,* from try;7 ?' j, D3 Y# F4 ~, U
.echo on
. D" R4 V% B$ {$ @" y& t--
$ }. S; P. z, A2 W4 z4 V' b1 i+ F-- Only these 2 rows should be present:
; d& e7 a/ p. @6 E: c; f-- 1|a1||
, k8 G. A* h0 O& q9 U-- 2||d2|x22 [$ g" o6 m: H6 o
--' B6 |" O  O) V, V9 M
但是,当我只希望前两个成功时,所有14个插入都成功。7 Q0 ]4 _6 Q  z& f7 t8 B
                0 J: Z7 p3 l5 X; W; q
解决方案:
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则