回答

收藏

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

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

考虑一个包含可空列abc,def和xyz的表。如何执行:8 ~) Q) b) O1 Z0 a- Y6 t( O+ R
[ol]如果’abc’不为null,则将1(’abc’)设置为UNIQUE,并且
0 _' w7 n8 F: x4 [( K! m如果’def’和’xyz’都不为null,则将2(’def,xyz’)设置为UNIQUE,并且% x1 i" H: T( W2 Y$ a* b
上述集合中只有一个有效(包含非null)。) E7 w) w* i# c+ ]: m: }% h# R$ g# P
[/ol]
! z8 e0 s1 _+ m8 V, C( m1 Y' {7 w这是我尝试过的代码:8 j6 V- f7 [6 g* O; K% S
--# sqlite3 --version
$ U  I  W, k+ B) e--  3.13.0 ....
. H$ h$ \4 h# ~" A$ _DROP TABLE IF EXISTS try;
( H- M1 Z9 x9 WCREATE TABLE try(
$ M/ X$ z% Z* G    -- 'abc' should be null,                  when 'def' and 'xyz' are not null.
% P7 Z1 |& }$ |4 k5 H8 f6 r    -- 'abc' should be not be null,           when 'def' and 'xyz' are null.
9 |- @1 d& y! S    -- 'def' and 'xyz' should be null,        when 'abc' is not null.$ u6 F& ^' G+ ^  A
    -- 'def' and 'xyz' should be not be null, when 'abc' is null.
0 A, g% L( ^! A5 q    abc  TEXT,
- g1 Z$ X/ A8 H8 {9 f) w2 ~) b    def  TEXT,  }6 ~& ~$ U& U# P. Y
    xyz  TEXT,
9 w( I8 p; L& D% i" d: \    CONSTRAINT combo_1 UNIQUE(abc),* R* i7 ~/ s5 V2 B( H/ R. ?
    CONSTRAINT combo_2 UNIQUE(def, xyz)0 z3 {& m' {# L/ r
);* N0 e0 z  H0 d$ ~: c) R5 r# U
INSERT into try(abc)            VALUES("a1");              -- should succeed4 B3 j7 z( ~; Z3 g2 b3 p8 B4 y/ I  e
INSERT into try(def, xyz)       VALUES("d2", "x2");        -- should succeed2 C5 @% b8 s0 C) B" Y
--
; y- b0 ~9 O: T" @, VINSERT into try(abc)            VALUES(null);              -- should not be allowed7 }7 J+ P, t6 K: B& ~
INSERT into try(abc, def)       VALUES("a4", "d4");        -- should not be allowed
( Y$ V! j! K. ~9 J' E  LINSERT into try(abc, xyz)       VALUES("a5", "x5");        -- should not be allowed
; }) E( Z" j6 W! P$ I8 A' [( _INSERT into try(abc, def, xyz)  VALUES("a6", "d6", "x6");  -- should not be allowed! E3 M7 p/ G2 O2 x  ~
--- K% _! v% O) ^$ f: D7 Q
INSERT into try(def)            VALUES(null);              -- should not be allowed8 n, b8 X/ n2 P
INSERT into try(def)            VALUES("d8");              -- should not be allowed0 `! Y; z1 r  C
--1 G" Y2 K9 a! p% c5 w3 t
INSERT into try(xyz)            VALUES(null);              -- should not be allowed% Q* _$ }# D' z7 @$ U* \
INSERT into try(xyz)            VALUES("x10");             -- should not be allowed
% S! k0 s) t  a# U3 a: D--" n1 {/ \, p3 v9 T
INSERT into try(def, xyz)       VALUES(null, null);        -- should not be allowed' ?0 D) p" m' T4 i' k2 f
INSERT into try(def, xyz)       VALUES("d12", null);       -- should not be allowed$ G3 G1 f' _  c8 E4 {
INSERT into try(def, xyz)       VALUES(null, "x13");       -- should not be allowed
) q: j3 C& u; d: [( \, sINSERT into try(abc, def, xyz)  VALUES(null, null, null);  -- should not be allowed
. N5 F8 z+ k" X( a! N.headers ON
- _9 O$ |1 z- cselect rowid,* from try;0 F4 d. T/ [/ `1 D; l/ y
.echo on1 L6 p# c8 I  e1 U2 ?+ o' ~
--
, }5 h% k1 k2 k+ q% J-- Only these 2 rows should be present:2 E1 {" R+ `  y4 Z0 |: I5 n
-- 1|a1||$ h( r) B6 d5 Q4 z5 Y8 ]7 {
-- 2||d2|x2( L. Q3 l1 `, R% [
--
0 @, h* ]6 w: d, S( \2 `% L但是,当我只希望前两个成功时,所有14个插入都成功。3 f% M+ [+ K/ I. }" a2 a$ c' Y, u
                % x/ h; W4 N* L" w
解决方案:
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则