想象一下这样的表:
+-----+-------+
| id | value |
+-----+-------+
| id1 | val1 |
| id2 | val2 |
+-----+-------+
而id
为PRIMARY KEY
而value
有UNIQUE
约束。
我想要做的是使用基于其主键插入或更新条目的查询,但如果违反了唯一约束,将失败。
例如,如果我尝试插入id1, val2
,我希望查询失败,而插入id1, val3
应该更新第一行。
我在sqlite3中观察到的是,如果我使用INSERT OR REPLACE
插入id1, val2
,它将替换两个现有条目。我还看了一下sqlite的ON CONFLICT
子句,但似乎没有办法区分UNIQUE
或PRIMARY KEY
约束违规。
有没有办法用sqlite做这样的事情,还是有其他方法来处理这样的情况?
答案 0 :(得分:0)
OR REPLACE子句使用任何唯一约束(包括主键约束)来检测冲突。
如果内置行为不符合您的要求,您必须自己动手:
c.execute("UPDATE MyTable SET val = ? WHERE id = ?;", [newValue, id])
if c.rowcount == 0:
c.execute("INSERT INTO MyTable(val, id) VALUES (?, ?);", [newValue, id])
答案 1 :(得分:0)
您可以通过如下创建表来实现此目的:
CREATE TABLE test (
id INTEGER,
value VARCHAR(32) UNIQUE ON CONFLICT FAIL,
PRIMARY KEY(Id) ON CONFLICT REPLACE
);
关键是要为不同的列定义不同的ON CONFLICT
子句。在插入具有冲突PK的新记录时,PRIMARY KEY(Id) ON CONFLICT REPLACE
将导致sqlite替换记录,而在插入value VARCHAR(32) UNIQUE ON CONFLICT FAIL
违反value
约束时,UNIQUE
导致sqlite失败。
这将在插入具有相同主键的新记录时更新现有值,但 如果尝试插入具有不同主键和相同值的两条记录,则会失败。
例如
INSERT INTO test VALUES (1, "test");
INSERT INTO test VALUES (1, "update");
将导致
SELECT * FROM test;
1|update
但在新PK中插入相同的值
INSERT INTO test VALUES (2, "update");
将得到Error: UNIQUE constraint failed: test.value
。
答案 2 :(得分:-1)
Jan,希望这会对您有所帮助:https://www.sqlite.org/lang_conflict.html