在SQLite中如何使用IF NOT EXISTS

85

我试图将这行代码从MS SQL Server移植到SQLite。

IF NOT EXISTS(SELECT 1 FROM EVENTTYPE WHERE EventTypeName = 'ANI Received') 
    INSERT INTO EVENTTYPE (EventTypeName) VALUES ('ANI Received');

看起来SQLite不支持IF NOT EXISTS,或者至少我无法使其工作。

我错过了什么简单的东西吗?有没有解决办法?

4个回答

130

这个怎么样?

INSERT OR IGNORE INTO EVENTTYPE (EventTypeName) VALUES 'ANI Received'

(由于我没有SQLite,因此未经测试...但是这个链接非常详细。)

此外,以下内容也应该有效:

INSERT INTO EVENTTYPE (EventTypeName)
SELECT 'ANI Received'
WHERE NOT EXISTS (SELECT 1 FROM EVENTTYPE WHERE EventTypeName = 'ANI Received');

15
谢谢。但是需要注意的是,只有在事件类型名称设置为唯一时,INSERT OR IGNORE 才能起作用。 - AngryHacker
2
真的。我认为它是唯一的,因为它在示例SQL中的使用方式。如果不是,应该使用第二种方法。 - beach
如果EventTypeName不唯一,第二种方法真的可以使用吗?我正在尝试做类似的事情,但我发现SELECT WHERE NOT EXISTS子句返回多行,实际上每一行都是(EventTypeName != 'ANI Received')的等效值为true。 - Michael
意图是让EventTypeName成为唯一的。如果新值“ANI Received”在表EVENTTYPE中不存在,它才会被插入到该表中。这就是WHERE NOT EXISTS的作用。SELECT WHERE NOT EXISTS子句只能返回单行;没有FROM子句 - 没有办法返回多行。希望这样可以澄清问题。 - beach
1
这是非常糟糕的编码风格。每次出现错误时,查询都会静默失败!从文档中可以看到: IGNORE 当适用约束违规时,IGNORE 解决算法会跳过包含约束违规的那一行,并继续处理 SQL 语句的后续行,就像什么都没有发生一样。在使用 IGNORE 冲突解决算法时不会返回错误。其他在包含约束违规的行之前和之后的行将正常插入或更新。 - ManuelSchneid3r
@ManuelSchneid3r 这就是关键。 OP 想要插入尚不存在于表中的行(主键)。 OP 不希望每个主键违规都出现错误。 这模拟了原始问题中的 MS SQL 代码。 - beach

19
如果您想忽略现有值的插入,则您的表中必须有一个键字段。只需创建一个带有主键字段的表,例如:

CREATE TABLE table_name (key_field data_type PRIMARY KEY, ...)

CREATE TABLE IF NOT EXISTS TblUsers (UserId INTEGER PRIMARY KEY, UserName varchar(100), ContactName varchar(100),Password varchar(100));

然后在表中执行插入或替换/插入或忽略查询,例如:

INSERT OR REPLACE INTO TblUsers (UserId, UserName, ContactName ,Password) VALUES('1','UserName','ContactName','Password');

它不会让其重新进入现有的主键值... 这就是您可以检查表中是否存在某个值的方式。


1

你可以通过数学方法使用“NOT EXISTS”,即反转“EXISTS”的输出:

SELECT (1-EXISTS(<Your_SELECT>));

您的SELECT语句是:SELECT 1 FROM EVENTTYPE WHERE EventTypeName = 'ANI Received'

如果exists为1,则1-1的结果为0。如果exists为0,则1-0的结果为1。


1

您还可以使用表的KEY字段设置约束,并设置On Conflict "Ignore"。

当出现适用的约束违规时,IGNORE解决算法会跳过包含约束违规的一行,并继续处理后续的SQL语句行,就好像什么都没有发生一样。在包含IGNORE冲突解决算法的情况下,插入或更新了包含约束违规的行之前和之后的其他行。使用IGNORE冲突解决算法时不会返回错误。

SQLite文档


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接