回答

收藏

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

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

考虑一个包含可空列abc,def和xyz的表。如何执行:. u: {  ~2 u8 d. K: ~8 ^& y5 \( c
[ol]如果’abc’不为null,则将1(’abc’)设置为UNIQUE,并且0 v8 i. y) n4 E
如果’def’和’xyz’都不为null,则将2(’def,xyz’)设置为UNIQUE,并且
$ r0 v0 f0 Z8 M; F6 [上述集合中只有一个有效(包含非null)。1 _6 g8 v6 C" q
[/ol]! g& k; V" s* v( U- x, W$ V
这是我尝试过的代码:
' ^/ K) z4 K: `3 ~# C  W--# sqlite3 --version
7 S' ^, B, o, j2 N3 o! q--  3.13.0 ....
* Q0 D% K; w! ^: k7 X; n8 Z0 NDROP TABLE IF EXISTS try;
% J2 I" D* h' B# `4 w7 XCREATE TABLE try(
5 j2 @' t% p  J6 q( l    -- 'abc' should be null,                  when 'def' and 'xyz' are not null.
9 b4 C# W  J  {2 J, {( a3 |    -- 'abc' should be not be null,           when 'def' and 'xyz' are null.
, M  ?5 `+ p( A    -- 'def' and 'xyz' should be null,        when 'abc' is not null.
9 q( a2 d4 v8 b6 d5 j    -- 'def' and 'xyz' should be not be null, when 'abc' is null.
; A2 o1 F0 ~. D: h    abc  TEXT,! d3 J& {1 l8 |8 h& z3 N( S: O
    def  TEXT,
3 E0 _$ z. b, U2 X) O, Y9 V& ]    xyz  TEXT,! j# I5 x$ g- s) n
    CONSTRAINT combo_1 UNIQUE(abc),
1 s, S* _) ]+ b! P% y. R    CONSTRAINT combo_2 UNIQUE(def, xyz)
, ^# k- U. B  q3 }$ z);, x) z- B" H/ P
INSERT into try(abc)            VALUES("a1");              -- should succeed
0 m+ J. s3 \, j2 RINSERT into try(def, xyz)       VALUES("d2", "x2");        -- should succeed
& x& @5 }3 m1 u% [5 j7 V" V1 _--& W4 X2 k# l; g' C
INSERT into try(abc)            VALUES(null);              -- should not be allowed- K; N  @# c/ Q* T$ \9 i7 o
INSERT into try(abc, def)       VALUES("a4", "d4");        -- should not be allowed
4 }3 k2 j+ c2 W& M& ?% V& kINSERT into try(abc, xyz)       VALUES("a5", "x5");        -- should not be allowed
! s: J, F( z7 L+ A" \; c1 nINSERT into try(abc, def, xyz)  VALUES("a6", "d6", "x6");  -- should not be allowed
) M9 c+ p; y$ s--4 h4 T; K1 i% p# Z
INSERT into try(def)            VALUES(null);              -- should not be allowed
1 Z1 ^+ I% y  u- p3 b6 iINSERT into try(def)            VALUES("d8");              -- should not be allowed' w# Q0 ^; |& W! S3 I; g
--
0 X' {* ?, L8 M, t$ AINSERT into try(xyz)            VALUES(null);              -- should not be allowed  J5 |' Q% ]5 |# ?+ }
INSERT into try(xyz)            VALUES("x10");             -- should not be allowed$ g5 ]; P" I; C" O  F/ Z/ o
--- X8 i- C6 {. ?! J
INSERT into try(def, xyz)       VALUES(null, null);        -- should not be allowed; R4 r( P1 h7 V
INSERT into try(def, xyz)       VALUES("d12", null);       -- should not be allowed
8 |& u0 G! Z/ [' yINSERT into try(def, xyz)       VALUES(null, "x13");       -- should not be allowed  T- l. }  K- V  j8 \3 z1 r  |
INSERT into try(abc, def, xyz)  VALUES(null, null, null);  -- should not be allowed4 f, t  l; H9 o& i- y* Q! w' W" }! A- y
.headers ON4 _% ]2 n) m0 y
select rowid,* from try;& H: q0 y" `0 Z* p0 ?
.echo on, q  H3 P" c+ I0 J) \
--! {( F; Q7 A: ~. t  N8 O  B7 E& V
-- Only these 2 rows should be present:! C$ x6 ~& }9 J' H! c  h. _' _7 V
-- 1|a1||8 v4 |1 g' t0 f1 t. T$ V3 S
-- 2||d2|x25 h/ S2 I4 h4 v2 ^
--
' b) X2 X0 h  b; C4 j但是,当我只希望前两个成功时,所有14个插入都成功。
9 c) E+ W' D; n5 G- h                8 g9 F) K) V- J& E
解决方案:
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则