SQLite支持SCOPE_IDENTITY吗?

24

我正在尝试执行一个简单的INSERT,并返回标识(自增主键)。我已经试过

cmd.CommandText = "INSERT INTO Prototype ( ParentID ) VALUES ( NULL ); SELECT SCOPE_IDENTITY();";

我收到了以下错误:

EnvironmentError:SQLite 错误
没有这样的函数: SCOPE_IDENTITY

SQLite 支持 SCOPE_IDENTITY 吗?
如果支持,如何使用它?
如果不支持,有哪些(最好是“线程安全”的)替代方案?

3个回答

28

23

1
sqlite3_last_insert_rowid()是线程安全的吗?它是否像SCOPE_IDENTITY一样仅限于当前作用域? - Greg
1
阅读文档。当前连接上的最后身份验证。 - Robert Wagner

1
last_insert_rowid()返回的是最后一次插入到任何表中的行ID。正如其他答案中提到的那样,绝对不是线程安全的。
如果您绝对需要确保返回正确的行ID,而不受线程、异步等影响(例如,如果您打算在另一个表中使用rowid作为外键),可以采取以下方法:
1.在所需的表中插入一个文本列(这将保存GUID); 2.手动生成一个GUID(使用您语言中可用的任何库),并将其保存在内存中; 3.将您的数据与刚生成的GUID一起插入到表中; 4.通过last_insert_rowid()检索(假定的)rowid; 5.使用此rowid从您的表中检索行(或仅检索GUID); 6.将检索到的行中的GUID与您仍然保存在内存中的GUID进行比较。
如果它们相同,那么您就拥有了正确的rowid; 如果它们不同,则需要查询表以查找与您在内存中保存的GUID匹配的内容,以获取正确的rowid。
显然,这种解决方案存在相当大的性能缺陷,你需要权衡数据不匹配的风险是否超过性能损失。在我的情况下,我需要确保数据的完整性高于一切,因此性能受到影响是可以接受的。(我无法说这会有多大影响。)
你可能会想跳过第四步和第五步,使用GUID获取rowid;你也可能只是使用GUID作为主要标识符和外键。毕竟,这些做法可以使代码更简单,表格中的列也更少...但是要抵制这种冲动。整数作为主要标识符很容易进行索引,这使得它们在WHERE子句和JOINS中更快/更有效率;GUID或字符串就不能像整数那样进行索引。

确实如此,使用GUID而不是int进行索引,但组合GUID可以提高效率。 - infocyde

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