首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >SQLite数据库插入不知何故正在消失?

SQLite数据库插入不知何故正在消失?
EN

Stack Overflow用户
提问于 2016-05-12 05:01:47
回答 2查看 294关注 0票数 0

我的Android应用程序有一个非常奇怪的问题,当我向DB表插入一个值时,第一个条目不知怎么就消失了。然而,随后的任何条目看起来都很好。

更具体地说,我的应用程序的一部分允许用户创建一个简单的日志,在其中输入一些文本,当他们保存它时,它会显示在日志条目的列表中。但是,当我试图将第一个条目插入到一个空表时,该条目不会被显示,数据库也不会在查询计数时指示有任何数据。

有趣的是,当我查看数据库插入调用(SQLiteDatabase.insert())的返回时,我看到返回了一个有效的行号。实际上,当我查看保存到数据库的任何日志条目时,行号都会正确地递增。根据文档,我的理解是,如果返回一个非负数,插入就成功了。

下面的代码从我的EditText中获取AlertDialog的结果,创建一个新的日志条目,并调用insert方法:

代码语言:javascript
运行
复制
newPainLogEntryDialog.setPositiveButton("Save",
                        new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int which) {
                                //make new pain log entry
                                PainLog painLog = new PainLog();
                                painLog.setPainEntry(input.getText().toString());
                                painLog.setPainDateTime(Calendar.getInstance());

                                Database.init(PainLogTab.this.getActivity());
                                Database.createPainLog(painLog);
                                updatePainLogList();

                                //display success to user
                                Toast.makeText(PainLogTab.this.getActivity(),
                                        "Log entry saved", Toast.LENGTH_SHORT).show();
                            }
                        });

Database.createPainLog()的代码:

代码语言:javascript
运行
复制
public static long createPainLog(PainLog painLog) {
        ContentValues cv = new ContentValues();
        cv.put(COLUMN_PAINLOG_ENTRY, painLog.getPainEntry());
        cv.put(COLUMN_PAINLOG_DATETIME, painLog.getPainDateTimeString());

        return getDatabase().insert(PAINLOG_TABLE, null, cv);
    }

Toast消息之前的最后一个调用是updatePainLogList(),它获取所有DB条目:

代码语言:javascript
运行
复制
public void updatePainLogList(){
        Database.init(PainLogTab.this.getActivity());
        final List<PainLog> painLogs = Database.getAllPainLogs();
        painLogListAdapter.setPainLogs(painLogs);
        Log.d(getClass().getSimpleName(), "number of painLogs found: " + painLogs.size());

        getActivity().runOnUiThread(new Runnable() {
            public void run() {
                // reload content
                PainLogTab.this.painLogListAdapter.notifyDataSetChanged();
                if(painLogs.size() > 0){
                    getView().findViewById(android.R.id.empty).setVisibility(View.INVISIBLE);
                }else{
                    getView().findViewById(android.R.id.empty).setVisibility(View.VISIBLE);
                }
            }
        });
    }

为了完成,getAll()的主体及其附带的方法getCursor():

代码语言:javascript
运行
复制
public static Cursor getPainLogCursor() {
        String[] columns = new String[] {
                COLUMN_PAINLOG_ID,
                COLUMN_PAINLOG_ENTRY,
                COLUMN_PAINLOG_DATETIME
        };

        return getDatabase().query(PAINLOG_TABLE, columns, null, null, null, null,
                null);
    }

    public static List<PainLog> getAllPainLogs() {
        List<PainLog> painLogs = new ArrayList<PainLog>();
        Cursor cursor = Database.getPainLogCursor();
        if (cursor.moveToFirst()) {

            while (cursor.moveToNext()) {
                PainLog painLog = new PainLog();
                painLog.setId(cursor.getInt(IDX_PAINLOG_ID));
                painLog.setPainEntry(cursor.getString(IDX_PAINLOG_ENTRY));
                painLog.setPainDateTime(cursor.getString(IDX_PAINLOG_DATETIME));

                painLogs.add(painLog);
            }
        }
        cursor.close();
        return painLogs;
    }

现在,通过一些代码,我可以解释到目前为止所采取的调试步骤。如前所述,当我查看DB insert的返回时,我得到了一个正的、非零的数字。但是,当我试图在紧接的update方法中打印日志数量(在途中没有删除或任何调用)时,它将显示0,实际上,如果我跟随游标,我发现它从未进入将日志添加到所显示的列表中的循环,也表明它没有拾取条目。

我尝试在事务中设置DB insert,以便可以手动提交,但这也没有帮助。让我更感兴趣的是,我在我的应用程序的其他地方也有类似的功能,我保存用户的首选项并将它们显示在列表中,而这不存在同样的问题.我已经与这段代码进行了比较,找不到可能导致它的任何差异。

总之,我的问题有两个方面:为什么我在空表上的第一次插入没有出现,而下面的所有插入都没有问题?为什么我要从数据库插入获得有效的返回,然后在查询缺少的数据时立即进行插入?

)预先感谢您能提供的任何帮助:)

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-05-12 05:40:35

if (cursor.moveToFirst()) { while (cursor.moveToNext()) {

这将跳过光标中的第一行。moveToFirst()移到第一行,moveToNext()移动到下一行,跳过第一行。

您可以用while (cursor.moveToNext())来代替它。当您从查询中获得游标时,它首先放在index -1,即位于第一个查询之前的行。

票数 2
EN

Stack Overflow用户

发布于 2017-07-29 09:45:25

代码语言:javascript
运行
复制
if (cursor.moveToFirst()) {
    while (cursor.moveToNext()) {

这是最好的解决办法.

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37177655

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档