SQLite是否支持SCOPE_IDENTITY?

时间:2008-11-20 07:19:58

标签: sql sqlite

我正在尝试执行简单的INSERT并返回标识(自动递增主键)。我试过了

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

我收到以下错误

EnvironmentError: SQLite error
no such function: SCOPE_IDENTITY

SQLite是否支持SCOPE_IDENTITY?
如果是这样,我该如何使用它? 如果没有,我的(最好是“线程安全的”)替代品是什么?

3 个答案:

答案 0 :(得分:25)

如果您没有使用C接口进行编程并希望从SQL命令执行此过程,请尝试:SELECT last_insert_rowid()

http://www.sqlite.org/lang_corefunc.html

答案 1 :(得分:19)

查看FAQsqlite3_last_insert_rowid()函数会执行此操作。但是要小心触发。

答案 2 :(得分:0)

last_insert_rowid()从最后插入ANY表的结果得到行ID。绝对不是其他答案中提到的线程安全。

如果绝对需要以确保您获得正确的行ID,则与线程,异步等无关(例如,如果您打算将rowid用作另一个ID中的外键)表格),这是一种方法:

  1. 将文本列插入所需的表(这将保留一个GUID)
  2. 手动生成一个GUID(使用您语言中可用的任何库)并将其保存在内存中
  3. 将您的数据与刚刚生成的GUID一起插入表中
  4. 通过last_insert_rowid()检索(假定的)rowid
  5. 使用此rowid从表中检索行(或仅GUID)
  6. 将检索到的行中的GUID与您仍在内存中的GUID进行比较
    • 如果它们是相同的快乐的日子,那么您具有正确的rowid
    • 如果它们不同,则需要查询表以查找与内存中GUID的匹配,以获取正确的rowid

显然,此解决方案具有很大的性能缺陷,您需要对数据不匹配的风险是否超过性能损失进行判断。就我而言,我需要首先确定数据的完整性,以便性能受到冲击。 (我不能说这是多么大的打击。)

您可能会希望跳过第4步和第5步,并使用GUID获取行号;您也可能会希望只使用GUID作为主标识符和外键。所有这些简化后,代码将更简单,并且表中的列也更少了……抵制它。作为主要标识符的整数易于索引,这使它们在WHERE子句和JOINS中更快/更有效;一个GUID或字符串不像整数一样索引。