【问题标题】:Android - SQLite database not updating rowAndroid - SQLite 数据库不更新行
【发布时间】:2018-08-26 06:15:06
【问题描述】:

在过去的几天里,我查看了大量类似的主题,但似乎没有一个对我的实际情况有所帮助,或者这只是我的经验不足。

我有一个执行 CRUD 操作的简单应用程序。我可以成功地在表中输入新行并删除它们,但是我的更新代码有问题,我找不到原因。让我感到困惑的是,它曾经工作过一次,然后无论我是创建新条目还是完全删除数据库并重新开始,都再也没有工作过。隔离一下我认为相关代码的操作流程如下。

单个项目位于 RecyclerView 中,并从内部类发送到要编辑和更新的活动:

public void onBindViewHolder(@NonNull ContactViewHolder holder, int position) {

        final String contactName = mCursor.getString(mCursor.getColumnIndex(ContactEntry.COLUMN_NAME));
        final int contactNumber = mCursor.getInt(mCursor.getColumnIndex(ContactEntry.COLUMN_PHONE_NUMBER));
        final String contactMail = mCursor.getString(mCursor.getColumnIndex(ContactEntry.COLUMN_EMAIL));
        final int currentPosition = position;

    holder.mEditContact.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Intent intent = new Intent(mContext, ContactUpdate.class);
                    intent.putExtra(CONTACT_POSITION, currentPosition);
                    intent.putExtra(EXTRA_NAME, contactName);
                    intent.putExtra(EXTRA_PHONE, contactNumber);
                    intent.putExtra(EXTRA_MAIL, contactMail);
                    mContext.startActivity(intent);
                }
            });

然后我将它们放入检索类并将值组织到适当的 EditText 视图中。我确信有一种更有效的方法,但我仍在学习:

Intent intent = getIntent();
        mPosition = intent.getIntExtra(ContactRecyclerAdapter.CONTACT_POSITION, 0);
        mContactName = intent.getStringExtra(ContactRecyclerAdapter.EXTRA_NAME);
        mContactPhone = intent.getIntExtra(ContactRecyclerAdapter.EXTRA_PHONE, 0);
        mContactMail = intent.getStringExtra(ContactRecyclerAdapter.EXTRA_MAIL);

        mUpdateName.setText(mContactName);
        mUpdatePhone.setText("" + mContactPhone);
        mUpdateMail.setText(mContactMail);

最后我更新行的方法:

private void updateData() {

        String name = mUpdateName.getText().toString();
        String getPhone = mUpdatePhone.getText().toString();
        int phone = Integer.parseInt(getPhone);
        String mail = mUpdateMail.getText().toString();

        SQLiteDatabase db = new ContactOpenHelper(this).getWritableDatabase();
        ContentValues values = new ContentValues();
        values.put(ContactEntry._ID, mPosition);
        values.put(ContactEntry.COLUMN_NAME, name);
        values.put(ContactEntry.COLUMN_PHONE_NUMBER, phone);
        values.put(ContactEntry.COLUMN_EMAIL, mail);

        String selection = ContactEntry._ID + " LIKE ?";

        String[] selectionArgs = { String.valueOf(mPosition)};

        db.update(ContactEntry.TABLE_NAME, values, selection, selectionArgs);
        db.close();
        startActivity(new Intent(this, ContactList.class));
    }

正在发生的事情是该行没有被更新。目前我输入了三个模拟条目。我在update() 行设置了一个断点,试图找出发生了什么。此条目的原始名称是“ted”,它是列表中的第三个。如果我编辑 EditText 字段并运行 updateData() 方法,当断点被击中时,它会正确显示编辑的值以及 2 的正确位置。但是数据库实际上并没有更新。我显然误解了这里的工作原理。

为避免臃肿,我只包含了我认为相关的内容,但如果需要更多信息,我很乐意添加。

最后,这是调试器在断点处的屏幕截图,显示了我认为正确的信息以及我完全困惑为什么它不工作的地方(我在末尾添加了一堆 g名称“ted”只是为了测试它是否有效)。

【问题讨论】:

    标签: java android sqlite


    【解决方案1】:

    如下更改您的更新电话

     int count = db.update(ContactEntry.TABLE_NAME, values, selection, selectionArgs);
    

    其中 count 显示受更新函数影响的行数,这将帮助您准确了解是否有任何更新的行。

    注意:-有时,当您不确切知道要查询的完整关键字时,我们会使用 like。例如,您可能知道您最喜欢的歌曲包含单词,电梯,但您不知道确切的名称。 如果您知道确切的值,请尝试使用:-

    String selection = ContactEntry._ID + " =? ";
    

    【讨论】:

    • 那是为了澄清 LIKE 之间的关系?和=?,这很有意义。我将在哪里使用变量 int count?我已经尝试将它分配给一个占位符以查看它返回的内容并且它没有返回任何内容。不幸的是,即使根据您的建议编辑了选择字符串,它仍然没有更新,所以我一定是在链条的早期破坏了一些东西,并会尝试一些其他的东西。
    • 您可以使用 count 变量 to , 使您的函数在 >0 时返回 true,否则返回 false。如果您的呼叫成功或在其他情况下执行某些操作,则可以使用返回的值继续前进。
    • 谢谢。肯定会取得一些进展。如果我理解正确(对不起,还在学习!)我将方法从返回 void 更新为返回 int。我在最后的返回处设置了一个中断,以查看发生了什么,并且计数返回 0。出于兴趣,我删除了 where 子句和 args,它返回 4,每行一个,然后更新该列中的每一行。我猜我的 where 子句有问题。
    【解决方案2】:
    String selection = ContactEntry._ID + " LIKE ?";
    
    String[] selectionArgs = { String.valueOf(mPosition)};
    

    将上面的代码更新为下面的代码

    String selection = ContactEntry._ID + " = ?";
    
    String[] selectionArgs = { String.valueOf(mPosition)};
    

    您想更新确切的行。但“LIKE”关键字主要用于搜索。

    此外,当您更新数据时,您正在打开您的活动。更新或插入数据库需要一些时间。当您的下一个活动开始时,数据库可能无法完成其写入操作。它可以引导您查看以前的数据。确保您的数据库已更新,然后更新视图。

    从模拟器中查看数据库是否具有新值。然后做进一步的工作。

    【讨论】:

    • 感谢您区分 LIKE ?和=?。不幸的是,它仍然没有更新。我理解您关于可能太早开始下一个活动的意思。为了进行测试,我删除了启动下一个活动的意图,并在 DB Browser for SQLite 中打开了 .db,并且该行没有更新。我怀疑尽管返回了我认为正确的值,但我还是搞砸了将位置传递给更新活动。目前我能想到的就这些了。
    【解决方案3】:

    尝试从 contentValues 中删除你的 _Id:

    //values.put(ContactEntry._ID, mPosition);
    

    我认为您不能更改 PRIMARY_KEY,您说要在哪一行更新:

    String[] selectionArgs = { String.valueOf(mPosition)};
    

    【讨论】:

      【解决方案4】:

      我现在已经解决了这个特殊的问题,答案很简单,有点尴尬。我试图将游标位置用于行 ID,但没有意识到数据库没有像游标那样使用零基索引,因此主键不匹配。

      当我使用 RecyclerView 时,我将以下行添加到我的 onBindViewHolder 并将变量传递给我的更新活动,然后可以在 selectionArgs 中使用它

      final long id = mCursor.getLong(mCursor.getColumnIndex(ContactEntry._ID));
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多