关于SQLite表约束:SQLite表约束 – 在多列上是唯一的

SQLite table constraint - unique on multiple columns

我可以在SQLite网站上找到关于此的语法"图表",但没有示例和我的代码崩溃。 我在单个列上有其他具有唯一约束的表,但我想在两列上向表添加约束。 这就是我所带来的SQLiteException,消息"语法错误"。

1
2
CREATE TABLE name (column defs)
UNIQUE (col_name1, col_name2) ON CONFLICT REPLACE

我这样做是基于以下几点:

表约束

为了清楚起见,我提供的链接上的文档说明CONTSTRAINT name应该在我的约束定义之前。

可能导致解决方案的一点是,无论我的括号列定义如何,调试器都会抱怨。

如果我放

1
...last_column_name last_col_datatype) CONSTRAINT ...

错误接近"CONSTRAINT":语法错误

如果我放

1
...last_column_name last_col_datatype) UNIQUE ...

错误接近"UNIQUE":语法错误


将UNIQUE声明放在列定义部分中:

1
CREATE TABLE name (column defs, UNIQUE (col_name1, col_name2) ON CONFLICT REPLACE);

工作范例:

1
CREATE TABLE a (i INT, j INT, UNIQUE(i, j) ON CONFLICT REPLACE);


好吧,您的语法与您包含的链接不匹配,它指定:

1
2
3
 CREATE TABLE name (column defs)
    CONSTRAINT constraint_name    -- This is new
    UNIQUE (col_name1, col_name2) ON CONFLICT REPLACE


请注意如何定义表格,因为插入时会得到不同的结果。 考虑以下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
CREATE TABLE IF NOT EXISTS t1 (id INTEGER PRIMARY KEY, a TEXT UNIQUE, b TEXT);
INSERT INTO t1 (a, b) VALUES
    ('Alice', 'Some title'),
    ('Bob', 'Palindromic guy'),
    ('Charles', 'chucky cheese'),
    ('Alice', 'Some other title')
    ON CONFLICT(a) DO UPDATE SET b=excluded.b;
CREATE TABLE IF NOT EXISTS t2 (id INTEGER PRIMARY KEY, a TEXT UNIQUE, b TEXT, UNIQUE(a) ON CONFLICT REPLACE);
INSERT INTO t2 (a, b) VALUES
    ('Alice', 'Some title'),
    ('Bob', 'Palindromic guy'),
    ('Charles', 'chucky cheese'),
    ('Alice', 'Some other title');

$ sqlite3 test.sqlite
SQLite version 3.28.0 2019-04-16 19:49:53
Enter".help" for usage hints.
sqlite> CREATE TABLE IF NOT EXISTS t1 (id INTEGER PRIMARY KEY, a TEXT UNIQUE, b TEXT);
sqlite> INSERT INTO t1 (a, b) VALUES
   ...>     ('Alice', 'Some title'),
   ...>     ('Bob', 'Palindromic guy'),
   ...>     ('Charles', 'chucky cheese'),
   ...>     ('Alice', 'Some other title')
   ...>     ON CONFLICT(a) DO UPDATE SET b=excluded.b;
sqlite> CREATE TABLE IF NOT EXISTS t2 (id INTEGER PRIMARY KEY, a TEXT UNIQUE, b TEXT, UNIQUE(a) ON CONFLICT REPLACE);
sqlite> INSERT INTO t2 (a, b) VALUES
   ...>     ('Alice', 'Some title'),
   ...>     ('Bob', 'Palindromic guy'),
   ...>     ('Charles', 'chucky cheese'),
   ...>     ('Alice', 'Some other title');
sqlite> .mode col
sqlite> .headers on
sqlite> select * from t1;
id          a           b              
----------  ----------  ----------------
1           Alice       Some other title
2           Bob         Palindromic guy
3           Charles     chucky cheese  
sqlite> select * from t2;
id          a           b              
----------  ----------  ---------------
2           Bob         Palindromic guy
3           Charles     chucky cheese  
4           Alice       Some other titl
sqlite>

虽然插入/更新效果相同,但id会根据表定义类型进行更改(请参阅第二个表,其中'Alice'现在有id = 4;第一个表正在执行更多我期望它执行的操作, 保持PRIMARY KEY相同)。 请注意这种效果。