是否可以在使用 sqlite 插入时忽略外键冲突?
Posted
技术标签:
【中文标题】是否可以在使用 sqlite 插入时忽略外键冲突?【英文标题】:Is it possible to ignore foreign key conflicts on insert with sqlite? 【发布时间】:2020-12-29 19:22:48 【问题描述】:这是我拥有的两个表的匿名表示:
create table if not exists master_node (
book_name text primary key on conflict ignore not null
);
create table if not exists category_table (
book_name text not null,
category text not null,
foreign key(book_name) references master_node(book_name) on delete cascade,
unique(book_name, category) on conflict ignore
);
当我在表格中插入代码时:
insert into master_node
(book_name)
values
('Harry Potter'),
('Foundation'),
('The Catcher in the Rye')
和
insert or ignore into category_table
(book_name, category)
values
(Harry Potter', 'Fiction'),
('Harry Potter', 'Fantasy'),
('Foundation', 'Fiction'),
('Foundation', 'Science Fiction'),
('The Catcher in the Rye', 'Coming-of-age'),
('Moby Dick', 'Adventure')
我收到[SQLITE_CONSTRAINT] Abort due to constraint violation (FOREIGN KEY constraint failed)
错误,事务被回滚。
我希望通过使用insert or ignore
能够简单地跳过违反外键约束的行。我一直无法找到一种方法来获得这种行为。 sqlite 是否提供了这样做的方法?
【问题讨论】:
如果要违反外键约束有什么意义?如果要添加master_node
中不存在的记录,则不要删除约束。
insert or ignore
仅忽略 UNIQUE 约束违规。
@Ivar 我希望 FK 约束阻止我添加违反约束的行。我只想要来自master_node
的具有book_name
的行,但是如果我正在执行批量插入并且我有违反约束的行,我只想忽略这些行,而不是回滚整个插入。
@forpas 是的,我注意到它只适用于 unique
和 check
,我只是在寻找相同的功能,但要使用外键约束。
这能回答你的问题吗? insert or ignore rows that violate foreign key constraints sqlite
【参考方案1】:
没有等效的INSERT OR IGNORE
,它仅适用于违反 UNIQUE 约束、违反 FOREIGN KEY 约束。
作为一种解决方法,您可以在 INSERT ... SELECT
语句中使用 EXISTS
:
WITH cte(book_name, category) AS (
VALUES
('Harry Potter', 'Fiction'),
('Harry Potter', 'Fantasy'),
('Foundation', 'Fiction'),
('Foundation', 'Science Fiction'),
('The Catcher in the Rye', 'Coming-of-age'),
('Moby Dick', 'Adventure')
)
INSERT INTO category_table (book_name, category)
SELECT c.book_name, c.category
FROM cte c
WHERE EXISTS (SELECT 1 FROM master_node m WHERE m.book_name = c.book_name)
请参阅demo。 结果:
> book_name | category
> :--------------------- | :--------------
> Harry Potter | Fiction
> Harry Potter | Fantasy
> Foundation | Fiction
> Foundation | Science Fiction
> The Catcher in the Rye | Coming-of-age
【讨论】:
谢谢。我希望能够使用 FK,因为无论如何我都需要它们进行级联删除,但是这个解决方案看起来是解决我的问题的最干净的方法。以上是关于是否可以在使用 sqlite 插入时忽略外键冲突?的主要内容,如果未能解决你的问题,请参考以下文章