gpt4 book ai didi

sqlite - 如何对具有主键和 UNIQUE 列的表执行更新插入

转载 作者:行者123 更新时间:2023-12-03 17:41:51 29 4
gpt4 key购买 nike

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
);

假设我插入一条记录:
INSERT INTO contacts (contact_id, first_name, last_name, email, phone)
VALUES (1, 'John', 'Jones', 'jjones@gmail.com', '888-867-5309');

我怎样才能做一个同时考虑 UNIQUE 约束( email )和 PK 约束( contact_id )的 upsert 以便它处理这两种情况,因为我不知道哪个约束会失败。

我尝试这样做:
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;

但我收到错误:

sqlite3.OperationalError: ON CONFLICT clause does not match any PRIMARY KEY or UNIQUE constraint



单独做它们工作得很好。
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;
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';

我知道我收到错误是因为列的组合不满足单个约束,它包含两个。但我将如何考虑两者?

最佳答案

由于您定义:

contact_id INTEGER PRIMARY KEY
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';

但是,您还定义了:
phone TEXT NOT NULL UNIQUE

所以你的表中有 2 个 UNIQUE 约束。
对于这种情况,如果您希望 SQLite 处理来自两列的冲突,您可以使用 (INSERT OR) REPLACE :
REPLACE INTO contacts (first_name, last_name, email, phone)
VALUES('Johny', 'Jones', 'john.jones@gmail.com', '888-867-5309')

您必须知道,如果没有冲突, REPLACE 会插入新行(对于您的情况下的列 emailphone),但如果存在冲突,则删除冲突的行(因为会有 2 个冲突的行,其中一个是 0x10465)另一个用于 email )并插入新行。

关于sqlite - 如何对具有主键和 UNIQUE 列的表执行更新插入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58414937/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com