Spa*_*yNZ 256 sqlite insert exists
我找到了一些经典的"将来"的解决方案,如果它已经存在,我将如何插入新记录或更新一个记录,但我无法让它们在SQLite中工作.
我有一个表定义如下:
CREATE TABLE Book
ID INTEGER PRIMARY KEY AUTOINCREMENT,
Name VARCHAR(60) UNIQUE,
TypeID INTEGER,
Level INTEGER,
Seen INTEGER
Run Code Online (Sandbox Code Playgroud)
我想要做的是添加一个具有唯一名称的记录.如果名称已存在,我想修改字段.
有人可以告诉我该怎么做?
jan*_*anm 309
看看http://sqlite.org/lang_conflict.html.
你想要的东西:
insert or replace into Book (ID, Name, TypeID, Level, Seen) values
((select ID from Book where Name = "SearchName"), "SearchName", ...);
Run Code Online (Sandbox Code Playgroud)
请注意,如果表中已存在该行,则不在插入列表中的任何字段将设置为NULL.这就是为什么ID列的子选择的原因:在替换的情况下,语句将其设置为NULL,然后将分配新的ID.
如果要在替换案例中的行中单独保留特定字段值,但在插入案例中将字段设置为NULL,也可以使用此方法.
例如,假设您想Seen独自离开:
insert or replace into Book (ID, Name, TypeID, Level, Seen) values (
(select ID from Book where Name = "SearchName"),
"SearchName",
5,
6,
(select Seen from Book where Name = "SearchName"));
Run Code Online (Sandbox Code Playgroud)
小智 80
您应该使用INSERT OR IGNORE命令后跟UPDATE命令:在以下示例中name是主键:
INSERT OR IGNORE INTO my_table (name, age) VALUES ('Karen', 34)
UPDATE my_table SET age = 34 WHERE name='Karen'
Run Code Online (Sandbox Code Playgroud)
第一个命令将插入记录.如果记录存在,它将忽略与现有主键冲突导致的错误.
第二个命令将更新记录(现在肯定存在)
gas*_*ard 62
您需要在表上设置约束以触发" 冲突 ",然后通过执行替换来解决此问题:
CREATE TABLE data (id INTEGER PRIMARY KEY, event_id INTEGER, track_id INTEGER, value REAL);
CREATE UNIQUE INDEX data_idx ON data(event_id, track_id);
Run Code Online (Sandbox Code Playgroud)
然后你可以发出:
INSERT OR REPLACE INTO data VALUES (NULL, 1, 2, 3);
INSERT OR REPLACE INTO data VALUES (NULL, 2, 2, 3);
INSERT OR REPLACE INTO data VALUES (NULL, 1, 2, 5);
Run Code Online (Sandbox Code Playgroud)
"SELECT*FROM data"将为您提供:
2|2|2|3.0
3|1|2|5.0
Run Code Online (Sandbox Code Playgroud)
请注意,data.id为"3"而不是"1",因为REPLACE执行DELETE和INSERT,而不是UPDATE.这也意味着您必须确保定义所有必需的列,否则您将获得意外的NULL值.
Bur*_*cin 32
首先更新它.如果受影响的行数 = 0,则插入它.它最简单,适用于所有RDBMS.
Ste*_*ing 17
INSERT OR REPLACE将其他字段(TypeID,Level)替换为默认值.
INSERT OR REPLACE INTO book(id, name) VALUES(1001, 'Programming')
Run Code Online (Sandbox Code Playgroud)
我正在使用这个
INSERT OR IGNORE INTO book(id) VALUES(1001);
UPDATE book SET name = 'Programming' WHERE id = 1001;
Run Code Online (Sandbox Code Playgroud)
你也可以使用
INSERT OR REPLACE INTO book (id, name)
VALUES (1001, 'Programming',
(SELECT typeid FROM book WHERE id = 1001),
(SELECT level FROM book WHERE id = 1001),
)
Run Code Online (Sandbox Code Playgroud)
但我认为第一种方法更容易阅读
Com*_*ool 10
Upsert是您想要的。UPSERT语法已添加到SQLite版本3.24.0(2018-06-04)中。
CREATE TABLE phonebook2(
name TEXT PRIMARY KEY,
phonenumber TEXT,
validDate DATE
);
INSERT INTO phonebook2(name,phonenumber,validDate)
VALUES('Alice','704-555-1212','2018-05-08')
ON CONFLICT(name) DO UPDATE SET
phonenumber=excluded.phonenumber,
validDate=excluded.validDate
WHERE excluded.validDate>phonebook2.validDate;
Run Code Online (Sandbox Code Playgroud)
请注意,此时实际的单词“ UPSERT”不是upsert语法的一部分。
正确的语法是
INSERT INTO ... ON CONFLICT(...) DO UPDATE SET...
如果您正在执行INSERT INTO SELECT ...选择,则至少需要使用连接语法WHERE true解决有关令牌的解析器歧义ON。
请注意,INSERT OR REPLACE...如果必须替换一条新记录,它将在插入之前删除该记录,如果您有外键级联或其他删除触发器,则可能会很糟糕。
如果您没有主键,则可以插入(如果不存在),然后执行更新.在使用此表之前,该表必须至少包含一个条目.
INSERT INTO Test
(id, name)
SELECT
101 as id,
'Bob' as name
FROM Test
WHERE NOT EXISTS(SELECT * FROM Test WHERE id = 101 and name = 'Bob') LIMIT 1;
Update Test SET id='101' WHERE name='Bob';
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
391739 次 |
| 最近记录: |