SQLite 游标中 moveToFirst() 的用途是啥

Posted

技术标签:

【中文标题】SQLite 游标中 moveToFirst() 的用途是啥【英文标题】:What is The use of moveToFirst () in SQLite CursorsSQLite 游标中 moveToFirst() 的用途是什么 【发布时间】:2012-09-08 19:52:39 【问题描述】:

我是一个编程新手 我在互联网上找到了这段代码,它工作正常

Cursor c=db.query(DataBase.TB_NAME, new String[] DataBase.KEY_ROWID,DataBase.KEY_RATE, DataBase.KEY_ROWID+"= 1", null, null, null, null);
        if(c!=null)
        
            c.moveToFirst();
        

但我无法理解的用法

if(c!=null)
    
        c.moveToFirst();
    

部分。它到底是做什么的,如果我删除了

if(c!=null)  c.moveToFirst(); 

部分,代码不起作用。

【问题讨论】:

【参考方案1】:

SQLiteDatabase.query() 的文档说查询方法返回:

“一个光标对象,位于第一个条目之前。”

调用moveToFirst() 做了两件事:它允许您测试查询是否返回了一个空集(通过测试返回值)并将光标移动到第一个结果(当该集不为空时)。请注意,为防止返回集为空,您发布的代码应该测试返回值(它没有这样做)。

moveToFirst() 的调用不同,if(c!=null) 的测试是无用的; query() 要么返回 Cursor 对象,要么抛出异常。它永远不会返回null

【讨论】:

兄弟你能在这个问题上给出解决方案或想法吗***.com/questions/29014212/…如果你能回复我很高兴。 但是如果 URI 只有一个数据,比如一个联系人,这有什么意义呢?例如,我有一个联系人选择器,而用户正在挑选一个联系人。谢谢霍普先生! @RuchirBaronia - 重点是以统一的方式处理所有案件。不能将其写入始终位于第一个条目,因为结果集可能为空。如果它被设计成在结果集只有一个元素的唯一情况下将Cursor 定位在第一个条目,那么 API 将更难使用,需要始终编写代码来单独处理这种情况.【参考方案2】:
if (c.moveToFirst()) 
  while(!c.isAfterLast())  // If you use c.moveToNext() here, you will bypass the first row, which is WRONG
    ...
    c.moveToNext();
   

【讨论】:

多亏了这个,我能够解决我的第一个项目总是从我的列表中丢失的问题。【参考方案3】:

Cursor 不是查询结果的 Row。游标是一个可以迭代查询结果行的对象。光标可以移动到每一行。 .moveToFirst() 方法将其移动到结果表的第一行。

【讨论】:

【参考方案4】:

moveToFirst() 方法将光标移动到第一行。它允许执行测试查询是否返回空集。这是它的实现示例,

if (cursor.getCount() == 0 || !cursor.moveToFirst()) 

return cursor.getLong(cursor.getColumnIndexOrThrow(ID_COLUMN)); 

cursor.close(); 

【讨论】:

【参考方案5】:

macio.Jun 说的对!

我们有如下代码:

    String sql = "select id,title,url,singer,view,info from cache where id=" + id;
    SQLiteDatabase db = getMaintainer().getReadableDatabase();
    Cursor query = db.rawQuery(sql, null);
    query.moveToFirst(); 
    while(query.moveToNext())
        DBMusicData entity = new DBMusicData();
        entity.setId(query.getString(query.getColumnIndex(FIELD_ID)));
        entity.setTitle(query.getString(query.getColumnIndex(FIELD_TITLE)));
        entity.setSinger(query.getString(query.getColumnIndex(FIELD_SINGER)));
        entity.setTitlepic(query.getString(query.getColumnIndex(FIELD_PICURL)));
        entity.setInfoUrl(query.getString(query.getColumnIndex(FIELD_INFO)));
        entity.setViews(query.getString(query.getColumnIndex(FIELD_VIEW)));
        Log.w(tag, "cache:"+ entity.toString());
    
    query.close();
    query=null;
    db.close();
    db=null;

如果缓存表中只有一条记录,query.moveToFirst();会导致没有记录返回。

【讨论】:

请检查逻辑错误:如果 cursor.moveToNext 返回 true,那么您在第一条记录上。调用 moveToNext 会将您的第一行跳过到下一行,并且您的第一行将永远不会被访问。在您检查 moveToFirst 返回 true 后,您的 while 循环将是一个 do while() 循环而不是 while 循环。

以上是关于SQLite 游标中 moveToFirst() 的用途是啥的主要内容,如果未能解决你的问题,请参考以下文章

Android 使用 SQLite 光标显示下一项或上一项

Xamarin.Android 使用 SQLite 出现 Index -1 requested, with a size of 10 异常

遍历游标

如何从 sqlite 游标中获取列值?

在带有 sqlite 的 Python 中是不是有必要关闭游标?

SQLite SELECT MAX() 查询返回 null 到游标?