http://en.wikipedia.org/wiki/Upsert
Insert Update stored proc on SQL Server
在 SQLite 中是否有一些我没有想到的聪明的方法来做到这一点?
基本上,如果记录存在,我想更新四列中的三列, 如果它不存在,我想用第四列的默认值 (NUL) 插入记录。
ID 是主键,因此 UPSERT 永远只有一条记录。
(我试图避免 SELECT 的开销,以便确定我是否需要更新或显然插入)
建议?
我无法在 SQLite 站点上确认 TABLE CREATE 的语法。 我没有构建演示来测试它,但它似乎不受支持。
如果是,我有三列,所以它实际上看起来像:
CREATE TABLE table1(
id INTEGER PRIMARY KEY ON CONFLICT REPLACE,
Blob1 BLOB ON CONFLICT REPLACE,
Blob2 BLOB ON CONFLICT REPLACE,
Blob3 BLOB
);
但前两个 blob 不会导致冲突,只有 ID 会 所以我假设 Blob1 和 Blob2 不会被替换(根据需要)
当绑定(bind)数据是一个完整的事务时,SQLite 中的更新,意思是 每个要更新的发送行都需要:Prepare/Bind/Step/Finalize 语句 与允许使用重置功能的 INSERT 不同
语句对象的生命周期是这样的:
- 使用 sqlite3_prepare_v2() 创建对象
- 使用 sqlite3_bind_ 接口(interface)将值绑定(bind)到主机参数。
- 通过调用 sqlite3_step() 运行 SQL
- 使用 sqlite3_reset() 重置语句,然后返回步骤 2 并重复。
- 使用 sqlite3_finalize() 销毁语句对象。
我猜 UPDATE 与 INSERT 相比速度较慢,但它与使用主键的 SELECT 相比如何?
也许我应该使用 select 读取第 4 列 (Blob3),然后使用 REPLACE 写入新记录,将原始第 4 列与前 3 列的新数据混合?
最佳答案
假设表中有三列:ID、NAME、ROLE
错误:这将为 ID=1 插入或替换所有列的新值:
INSERT OR REPLACE INTO Employee (id, name, role)
VALUES (1, 'John Foo', 'CEO');
错误:这将插入或替换 2 列...NAME 列将设置为 NULL 或默认值:
INSERT OR REPLACE INTO Employee (id, role)
VALUES (1, 'code monkey');
GOOD:使用 SQLite On conflict 子句 UPSERT support in SQLite! UPSERT 语法已添加到 SQLite 3.24.0 版!
UPSERT 是对 INSERT 的一种特殊语法添加,如果 INSERT 违反唯一性约束,它会导致 INSERT 表现为 UPDATE 或空操作。 UPSERT 不是标准 SQL。 SQLite 中的 UPSERT 遵循 PostgreSQL 建立的语法。
好但乏味:这将更新其中的 2 个列。 当 ID=1 存在时,NAME 不受影响。 当ID=1不存在时,名称将是默认的(NULL)。
INSERT OR REPLACE INTO Employee (id, role, name)
VALUES ( 1,
'code monkey',
(SELECT name FROM Employee WHERE id = 1)
);
这将更新其中的 2 列。 当ID=1存在时,ROLE不受影响。 当 ID=1 不存在时,角色将被设置为 'Benchwarmer' 而不是默认值。
INSERT OR REPLACE INTO Employee (id, name, role)
VALUES ( 1,
'Susan Bar',
COALESCE((SELECT role FROM Employee WHERE id = 1), 'Benchwarmer')
);
关于SQLite - UPSERT *不是* INSERT 或 REPLACE,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/418898/