SQLite之rowid与sqlite3_last_insert_rowid()

//返回最后一次insert的rowid,如果没有插入就返回0 (DB session断开后也返回0, 是保存在进程的内存中)
SELECT LAST_INSERT_ROWID();


//找到最大的rowid(如果是自定义的primaryKey, 比如 NumID  则都可以用,  反正是alias 别名)
SELECT  *,MAX(rowid) FROM Table_1004A;//推荐
SELECT  *,MAX(NumID  ) FROM Table_1004A;//推荐


SELECT  *,MIN(rowid) FROM Table_1004A;//推荐


//不推荐,再增加OrderBy DESC 等等
SELECT rowid FROM Table_1004A ORDER BY ROWID DESC LIMIT(1);
SELECT *,rowid FROM Table_1004A ORDER BY ROWID DESC LIMIT(1);


SELECT *,rowid "NAVICAT_ROWID" FROM "main"."Table_1004A" LIMIT 53000,1000


//时间: 0.03s
INSERT INTO "main"."Table_1004A"("ChipID", "ChipType", "BatchID", "T1_TestMode", "T1_Timestamp", "T1_Temp", "T1_ErrSaAddrNum", "T1_ErrSaAddr", "T1_ChipResult", "T1_HandlerResult", "T2_TestMode", "T2_Timestamp", "T2_Temp", "T2_ErrSaAddrNum", "T2_ErrSaAddr", "T2_ChipResult", "T2_RepairedSaAddr", "T2_HandlerResult", "Comment") VALUES (1301000100005001, 'XM1004_A_DWL', 100, 'ArrayWR', 1571106878, 120, 5, '1,2,3,4,5', 'Finish_MarchC', 1, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);


//结果显示53102 + 显示最后插入信息
SELECT LAST_INSERT_ROWID();
SELECT *,rowid FROM Table_1004A WHERE rowid= 53102;


//2句话,一句搞定
SELECT *,rowid FROM Table_1004A WHERE rowid=LAST_INSERT_ROWID();

1、背景知识

(1). ROWID

每个表默认都有 rowid 列,除非创建表时指定了 WITHOUT ROWID, 它现在是 64 位长的。在查询时用 select * from table1 里没有它,要显式的用 select rowid, * from table1 就会列出它来。

(2). ROWID 的别名

ROWID 除了可用 rowid 查出它之外,还可用别名 _ROWID_ 和 OID,都不分大小写的, 例如 select oid from table1。另外我们还可以自定义一个 ROWID 的别名,用 INTEGER PRIMARY KEY 标识的列也是 ROWID 的一个别名,比如我们用 id 来作为 ROWID 的别名。

ROWID 的表示也是个自增列,每个表有自己的计数器,和常见的数据库的自增列是一致的。

SQLite 的 ROWID 可不象 Oracle 的 ROWID, Oracle 的 ROWID 是纯内部的,标记着记录的物理位置,所以数据库导入导出 Oracle 的 ROWID 就会变了。更为可怕的是 SQLite 的 ROWID 是可以自己赋值的。

(3). 自增列序列表(也是 ROWID)

用 INTEGER PRIMARY KEY AUTOINCREMENT 标识的列就是个自增列,说到底它也是 ROWID  别名。数据库中存在自增列后,SQLite 就会创建一个 sqlite_sequence 表。所有表的自增列都共享这个表,sqlite_sequence 分别维护着每个自增列的当前值,所以自增列的计数也是单独的。它不象于 Oracle 中多个表在共用一个序列时,ID 值是交错的,Oracle 的序列的好处就是插入前可获知下一个序列值。


顺便说一下 VACUUM命令,这个命令能重建 ROWID 值。

https://yanbin.blog/sqlite-primary-rowid-autoincrement/


2、插入时注意事项

(1)当主键设置为自动增长的时候,主键的数据类型必须是integer类型,不能使long类型。

(2)插入的时候,如果罗列的列中没有自动增长列 ,自动增长列也是可以实现自动增长的,如一所示。

(3)插入的时候,如果罗列的列中有自动增长列,那么设置为null,可以实现自动增长,如二所示。

https://blog.csdn.net/scyatcs/article/details/12625521


3、读取刚插入的记录的ID

select last_insert_rowid() from 表名


SQLite数据库中的表均有一个特殊的rowid字段,它是一个不重复的64位有符号整数,默认起始值为1。

rowid别名为oid或_rowid_,但在创建表的SQL声明语句中只能使用rowid作为关键字。如果在创建表的时候设置了类型为integer的具有自动增长性的主键,那么这时的主键相当于是rowid的别名。
rowid只能是单调递增的,它由SQLite内部维护,不能自己指定。对于失败的插入操作,rowid也可能在原来的基础上执行了自增。删除或回滚操作并不会减小rowid的值。当rowid达到所能表示的最大值时,这时如果有新纪录要插入,系统就会从之前没有被使用过的(或从已经被删除的记录的)rowid中随机取出一个作为rowid。若没有可用的rowid,系统就会抛出SQLITE_FULL的错误。

rowid字段在表中默认是隐藏的,也就是说,除非SQL查询语句中指定返回rowid,否则查询结果不会包含有rowid字段。
可以在创建表时使用WITHOUT ROWID以声明不生成rowid字段,例如:

CREATE TABLE IF NOT EXISTS wordcount(

 word TEXT PRIMARY KEY,

 cnt INTEGER

) WITHOUT ROWID;

将关键字AUTOINCREMENT使用在声明为WITHOUT ROWID的表不但不起作用,还将引发一个错误。
SQLiteAPI 函数sqlite3_last_insert_rowid()可以取得最后一条插入的记录的rowid。但sqlite3_last_insert_rowid()是基于当前进程的。也就是说,sqlite3_last_insert_rowid()取到的是当前进程最后一次插入记录的rowid。对于不是当前进程插入的记录,sqlite3_last_insert_rowi()均返回0。sqlite3_last_insert_rowi()对应的SQL声明为last_insert_rowid(),例如:

select last_insert_rowid() from exam_tbl

————————————————
版权声明:本文为CSDN博主「venchia_lu」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/venchia_lu/article/details/50457274

原文地址:https://www.cnblogs.com/scotth/p/11676192.html