SQLite数据库插入有点消失吗?

时间:2016-05-12 05:01:48

标签: android database sqlite alertdialog

我的Android应用程序上有一个非常奇怪的问题,当我向DB表插入一个值时,第一个条目正在以某种方式消失。但是,任何后续条目都显得正常。

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

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

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

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()的代码:

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(),它获取所有数据库条目:

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():

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;
    }

现在有了一些代码,我可以解释到目前为止我采取了哪些调试步骤。如上所述,当我查看数据库插入的返回时,我得到一个正数,非零数字。但是,当我尝试在紧接着的更新方法中打印日志数量时(没有删除或在途中调用任何内容),它显示0,实际上如果我按照Cursor我发现它永远不会进入添加日志的循环到显示的列表,也表示它没有拿起条目。

我试图在事务中设置数据库插入,以便我可以手动提交,但这也无济于事。让我觉得更有趣的是我在我的应用程序的其他地方有类似的功能,我保存用户首选项并将它们显示在列表中,这不会遇到同样的问题...我已经比较了这段代码并且没有&# 39;找出导致它的任何差异。

总而言之,我的问题有两个方面:为什么我的第一张插页只显示在空白的桌子上,而后面的所有插页都没问题?为什么我从数据库插入中获得有效的返回,但是当我查询该数据时,它会立即在插入之后丢失?

提前感谢您提供的任何帮助:)

2 个答案:

答案 0 :(得分:2)

if (cursor.moveToFirst()) {

    while (cursor.moveToNext()) {

这会跳过光标中的第一行。 moveToFirst()移至第一行,moveToNext()移至下一行,跳过第一行。

您可以仅使用while (cursor.moveToNext())替换它。从查询中获取光标时,它首先放在索引-1处,即第一个之前的行。

答案 1 :(得分:-1)

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

这对它来说是最好的解决方案......