SQLite 中的“如果不存在则插入”语句
Posted
技术标签:
【中文标题】SQLite 中的“如果不存在则插入”语句【英文标题】:"Insert if not exists" statement in SQLite 【发布时间】:2013-10-20 15:34:16 【问题描述】:我有一个 SQLite 数据库。我正在尝试在表 bookmarks
中插入值(users_id
、lessoninfo_id
),前提是两者之前都不存在。
INSERT INTO bookmarks(users_id,lessoninfo_id)
VALUES(
(SELECT _id FROM Users WHERE User='"+$('#user_lesson').html()+"'),
(SELECT _id FROM lessoninfo
WHERE Lesson="+lesson_no+" AND cast(starttime AS int)="+Math.floor(result_set.rows.item(markerCount-1).starttime)+")
WHERE NOT EXISTS (
SELECT users_id,lessoninfo_id from bookmarks
WHERE users_id=(SELECT _id FROM Users
WHERE User='"+$('#user_lesson').html()+"') AND lessoninfo_id=(
SELECT _id FROM lessoninfo
WHERE Lesson="+lesson_no+")))
这给出了一个错误提示:
where 语法附近出现 db 错误。
【问题讨论】:
【参考方案1】:如果你不想有重复,你应该把它声明为一个表约束:
CREATE TABLE bookmarks(
users_id INTEGER,
lessoninfo_id INTEGER,
UNIQUE(users_id, lessoninfo_id)
);
(两列上的主键将具有相同的效果。)
然后可以告诉数据库你想silently ignore records that would violate such a constraint:
INSERT OR IGNORE INTO bookmarks(users_id, lessoninfo_id) VALUES(123, 456)
【讨论】:
获取新插入行的 ID 或已经存在的行的 ID 的最佳方法是什么,以便我可以将其插入到另一个具有该外键的表中?例如我有两张表person (id, name unique)
和cat (person_id, name unique)
,我想插入很多对(person_name, cat_name)
?
只有使用 SELECT 查询才能读取现有行的 ID。但这是一个不同的问题。
或许将ON CONFLICT IGNORE
添加到CREATE TABLE
会更方便一些
@rightaway717 “忽略”表示什么都没有发生;这个问题与更新无关。
@Hack06 android 的 insert() 行为不同;您应该将其替换为 insertOrThrow() 或 insertWithOnConflict()。【参考方案2】:
如果您有一个名为 memos 的表,它有两列 id
和 text
,您应该可以这样做:
INSERT INTO memos(id,text)
SELECT 5, 'text to insert'
WHERE NOT EXISTS(SELECT 1 FROM memos WHERE id = 5 AND text = 'text to insert');
如果记录已经包含text
等于“要插入的文本”且id
等于5 的行,则插入操作将被忽略。
我不知道这是否适用于您的特定查询,但也许它会提示您如何继续。
我建议您改为设计您的表格,以便不允许重复,如下面的@CLs answer
中所述。
【讨论】:
【参考方案3】:对于一个唯一的列,使用这个:
INSERT OR REPLACE INTO table () values();
欲了解更多信息,请参阅:sqlite.org/lang_insert
【讨论】:
这对我不起作用。它总是像插入或替换一样插入到 my_table (col1, col2) values('1','2');将添加多行 1 2 我可能会补充一点,如果将约束设置到位Unique(col1,col2)
并且您也有 col3,它会很好地工作,因为插入或忽略将失败,这会将 col3 更新为新值。 insert or replace into my_table values('1','2','5')
替换一行 '1','2','3'
【参考方案4】:
insert into bookmarks (users_id, lessoninfo_id)
select 1, 167
EXCEPT
select user_id, lessoninfo_id
from bookmarks
where user_id=1
and lessoninfo_id=167;
这是最快的方法。
对于其他一些 SQL 引擎,您可以使用包含 1 条记录的 Dummy 表。 例如:
select 1, 167 from ONE_RECORD_DUMMY_TABLE
【讨论】:
以上是关于SQLite 中的“如果不存在则插入”语句的主要内容,如果未能解决你的问题,请参考以下文章
mysql判断一条记录是否存在,如果存在,则更新此语句,如果不存在,则插入