22

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

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

我收到以下错误

环境错误:SQLite 错误
没有这样的功能:SCOPE_IDENTITY

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

4

3 回答 3

27

如果您不使用 C 接口进行编程并且想从 SQL 命令执行该过程,请尝试:SELECT last_insert_rowid()

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

于 2008-11-28T13:22:30.777 回答
21

查看常见问题解答sqlite3_last_insert_rowid()函数会做到这一点。不过要小心触发器。

于 2008-11-20T07:38:33.187 回答
0

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

如果您绝对需要确保返回正确的行 ID,无论线程、异步等如何(例如,如果您打算将 rowid 用作另一个表中的外键),这里有一种方法:

  1. 在所需的表中插入一个文本列(这将包含一个 GUID)
  2. 手动生成 GUID(使用您的语言中可用的任何库)并将其保存在内存中
  3. 将数据与刚刚生成的 GUID 一起插入表中
  4. 通过检索(假定的)rowidlast_insert_rowid()
  5. 使用此 rowid 从表中检索行(或仅 GUID)
  6. 将检索到的行中的 GUID 与内存中的 GUID 进行比较
    • if they are the same, happy days, you have the correct rowid
    • if they are different, you need to query the table for a match to the GUID you have in memory for the correct rowid

Obviously this solution has considerable performance drawbacks and you need to make a judgement call on whether the risks of mismatched data outweigh the performance toll. In my case, I needed to be certain of the integrity of my data above all else so it was fine for performance to take the hit. (Just how big a hit, I can't say.)

You might get the urge to skip the 4th and 5th steps and get the rowid using your GUID; you might also get the urge to just use the GUID as the primary identifier and foreign key. After all these would make the code simpler and mean less columns in your table... RESIST THAT URGE. Integers as primary identifiers are easily indexable which makes them faster/more efficient in WHERE clauses and JOINS; a GUID or string just doesn't index as well as an integer.

于 2019-09-11T03:07:49.573 回答