如何确定是否有任何插入/更新待处理?

时间:2015-03-06 16:48:49

标签: sqlite

我有一个进程在会话期间向数据库写入一些数据或没有数据。由于我需要记录每次提交并创建表的备份,因此我想限制提交次数,特别是不要进行任何空提交。

为了限制提交次数,我在会话开始时运行BEGIN TRANSACTION,这样我就可以进行批量提交。但是,由于我无法确定在会话期间写入了多少数据,有没有办法在我稍后调用COMMIT之前找出是否有任何INSERT / UPDATE(或DELETE)?

实现我想要的一种方法是(1)在会话开始时创建临时备份,(2)盲目提交,(3)将更新的数据库与备份进行比较,(4a) )如果两个文件不同,请重命名备份,记录提交,或者(4b)如果两个文件不同,并且会话结束,则删除备份。

我宁愿在最初的地方不做任何事情。我可以以某种方式检查日志文件以检查是否有任何挂起的写操作?

编辑

以更好地解释"无论如何都要提交"不是我正在寻找的答案

1 个答案:

答案 0 :(得分:1)

有一种方法......但我怀疑你会喜欢它。在事务中有一些pragma是no-op。拥有这些知识,你可以用一种相当愚蠢的方式确定是否有一个:

sqlite> pragma foreign_keys;
0
sqlite> begin;
sqlite> pragma foreign_keys = 1;
sqlite> pragma foreign_keys;
0

正如您所看到的,当尝试在事务内部更改它时,foreign_keys仍为0,但是当我们提交时:

sqlite> commit;
sqlite> pragma foreign_keys = 1;
sqlite> pragma foreign_keys;
1

价值很高兴。


但严重的是,请遵循 CL 的建议并提交。如果没有什么可以承诺,它不会造成任何伤害!


修改

既然你已经对你的问题进行了如此多的编辑,你就会清楚自己想要什么。转过身来,有办法。 sqlite3_total_changes()可以帮助你。您只需要将BEGIN的返回值存储起来,然后将其与COMMIT之前返回的值进行比较。这是一个小例子:

sqlite3 * db = 0;
sqlite3_open(":memory:", &db);

sqlite3_exec(db, "CREATE TABLE foo(a);", 0, 0, 0);

std::cout << "(1) " << sqlite3_total_changes(db) << std::endl;

sqlite3_exec(db, "INSERT INTO foo(a) VALUES(1);", 0, 0, 0);

std::cout << "(2) " << sqlite3_total_changes(db) << std::endl;

sqlite3_exec(db, "INSERT INTO foo(a) VALUES(2);", 0, 0, 0);

std::cout << "(3) " << sqlite3_total_changes(db) << std::endl;

sqlite3_exec(db, "BEGIN;", 0, 0, 0);
std::cout << "(4) " << sqlite3_total_changes(db) << std::endl;

sqlite3_exec(db, "DELETE FROM foo;", 0, 0, 0);

std::cout << "(5) " << sqlite3_total_changes(db) << std::endl;

sqlite3_exec(db, "COMMIT;", 0, 0, 0);

std::cout << "(6) " << sqlite3_total_changes(db) << std::endl;

输出结果为:

(1) 0
(2) 1
(3) 2
(4) 2
(5) 4
(6) 4