Tom*_*ash 5 sqlite auto-increment sql-insert
SQLite 新手,尝试了解 upsert 功能。
我有一个包含以下 DDL 的表:
CREATE TABLE contacts (
contact_id INTEGER PRIMARY KEY,
first_name TEXT NOT NULL,
last_name TEXT NOT NULL,
email TEXT NOT NULL UNIQUE,
phone TEXT NOT NULL UNIQUE
);
Run Code Online (Sandbox Code Playgroud)
假设我插入一条记录:
INSERT INTO contacts (contact_id, first_name, last_name, email, phone)
VALUES (1, 'John', 'Jones', 'jjones@gmail.com', '888-867-5309');
Run Code Online (Sandbox Code Playgroud)
我怎样才能做一个同时考虑 UNIQUE 约束 ( email) 和 PK 约束 ( contact_id) 的更新插入,以便它处理这两种情况,因为我不知道哪个约束会失败。
我尝试这样做:
INSERT INTO contacts (contact_id, first_name, last_name, email, phone)
VALUES (1, 'John', 'Jones', 'john.jones@gmail.com', '888-867-5309')
ON CONFLICT (contact_id, email) DO UPDATE
SET first_name='John', last_name='Jones', email='john.jones@gmail.com', phone='888-867-5309'
WHERE contact_id=1;
Run Code Online (Sandbox Code Playgroud)
但我收到错误:
sqlite3.OperationalError:ON CONFLICT 子句与任何 PRIMARY KEY 或 UNIQUE 约束不匹配
单独做它们效果很好。
INSERT INTO contacts (contact_id, first_name, last_name, email, phone)
VALUES (1, 'John', 'Jones', 'john.jones@gmail.com', '888-867-5309')
ON CONFLICT (contact_id) DO UPDATE
SET first_name='John', last_name='Jones', email='john.jones@gmail.com', phone='888-867-5309'
WHERE contact_id=1;
Run Code Online (Sandbox Code Playgroud)
INSERT INTO contacts (contact_id, first_name, last_name, email, phone)
VALUES (1, 'John', 'Jones', 'john.jones@gmail.com', '888-867-5309')
ON CONFLICT (email) DO UPDATE
SET first_name='John', last_name='Jones', email='john.jones@gmail.com', phone='888-867-5309'
WHERE email='john.jones@gmail.com';
Run Code Online (Sandbox Code Playgroud)
我知道我收到错误是因为列的组合不满足单个约束,它包含两个约束。但我该如何考虑两者呢?
既然你定义了:
contact_id INTEGER PRIMARY KEY
Run Code Online (Sandbox Code Playgroud)
contact_id是AUTOINCREMENT的,当您插入新行时,您不能显式地设置该列的值(尽管如果您这样做,如果不存在冲突,SQLite 不会抱怨)。
所以你需要的是:
INSERT INTO contacts (first_name, last_name, email, phone)
VALUES ('John', 'Jones', 'john.jones@gmail.com', '888-867-5309')
ON CONFLICT (email) DO UPDATE
SET first_name='John', last_name='Jones', email='john.jones@gmail.com', phone='888-867-5309';
Run Code Online (Sandbox Code Playgroud)
但是,您还定义了:
phone TEXT NOT NULL UNIQUE
Run Code Online (Sandbox Code Playgroud)
所以你的表中有两个UNIQUE约束。
对于这种情况,如果您希望 SQLite 处理两列的冲突,您可以使用(INSERT OR) REPLACE:
REPLACE INTO contacts (first_name, last_name, email, phone)
VALUES('Johny', 'Jones', 'john.jones@gmail.com', '888-867-5309')
Run Code Online (Sandbox Code Playgroud)
您必须知道,REPLACE如果没有冲突(对于列email和phone您的情况),则会插入新行,但如果存在冲突,则会删除冲突的行(因为会有 2 个冲突的行,一个用于email,另一个用于phone)并插入新行。
| 归档时间: |
|
| 查看次数: |
5810 次 |
| 最近记录: |