SQLite changes()计算不变的UPDATE

Mat*_*ias 6 sql sqlite

我对SQLite的changes()函数有疑问,根据文档," 返回最近完成的INSERT,DELETE或UPDATE语句更改或插入或删除的数据库行数 "(另请参阅底层C文档)/C++函数).

我希望使用此函数来检查执行UPDATE与单行有关的语句是否确实导致该行被更改.通过改变,我不仅仅意味着该行与语句的WHERE子句匹配.不,我的意思是,对于所讨论的行,执行后至少1列的值与之前相比实际上是不同的.如果你问我这是这个背景下变化的唯一正确定义.

所以我希望通过在执行语句后立即调用返回(行已更改)或(行未更改)来检测此类更改.但令我绝望的是,这似乎并没有像预期的那样奏效.changes()10UPDATE

请允许我举例说明:

CREATE TABLE People (Id INTEGER PRIMARY KEY AUTOINCREMENT, Name TEXT NOT NULL);
INSERT INTO People (Name) VALUES ("Astrid");
SELECT changes();
Run Code Online (Sandbox Code Playgroud)

这里changes()返回1,正如预期的那样,因为我们刚刚INSERT编了1行.

UPDATE People SET Name = "Emma" WHERE Id = 1;
SELECT changes();
Run Code Online (Sandbox Code Playgroud)

这里changes()返回1,按预期的1排是UPDATED(即实际上改变:在NamePersonId = 1"Astrid",但现在是"Emma").

UPDATE People SET Name = "John" WHERE Id = 200;
SELECT changes();
Run Code Online (Sandbox Code Playgroud)

这里changes()返回0,正如预期的那样,因为没有行Id = 200.

到现在为止还挺好.但是现在看看下面的UPDATE语句,它确实匹配现有行,但并没有真正改变它在所有(Name仍然设置为"Emma")...

UPDATE People SET Name = "Emma" WHERE Id = 1;
SELECT changes();
Run Code Online (Sandbox Code Playgroud)

这里changes()回来了1,而我当然希望0:-(.

如果函数被称为matched_rows()或类似的话,这可能是有意义的affected_rows().但对于一个被调用的函数changes(),并记录在案,这种行为让我感到不合逻辑,或充其量令人困惑.

所以,无论如何,有人可以解释为什么会发生这种情况,或者甚至更好地提出一种替代策略,以可靠(高效)的方式实现我的目标吗?

我能想到的只是实际做一些事情SELECT * FROM People WHERE Id = x,比较所有返回的列值和我将要在UPDATE语句中设置的值,从而决定是否需要执行UPDATE.但这不是很有效,对吧?当然,在这个玩具示例中它可能并不重要,但在我的实际应用程序中,我正在处理具有更多列的表,其中一些是(可能很大)BLOB.

CL.*_*CL. 10

数据库不比较旧值和新值; 即使值恰好相同,任何UPDATEd行也始终计为"已更改".该文件说,

UPDATE影响那些将WHERE子句表达式作为布尔表达式求值的结果为true的行.

如果要检查旧值,则必须明确地执行此操作:

UPDATE People SET Name = 'Emma' WHERE Id = 1 AND Name IS NOT 'Emma';
Run Code Online (Sandbox Code Playgroud)