有什么方法可以检查数据库中是否存在现有的唯一数据?

时间:2019-06-01 04:42:38

标签: java android database sqlite runtime-error

我的目标是在android studio中创建一个方法,以检查数据库中是否存在现有的用户名(唯一)。但是我的问题是,我不知道为什么我的已实现代码无法正常工作并在logcat中返回错误。该应用程序不会崩溃。

事实上,我已经尝试实现2种不同的方法。第一个方法是将数据库中所有选定的现有用户名放入一个arraylist中,并使用ArrayList.contains(username)方法查看该arraylist是否包含相似的用户名。

我尝试使用的另一种方法是在数据库中选择一个与我输入的用户名相同的用户名,然后查看它们是否相同。 (可能会使您感到困惑,但我会向您显示代码)。

MainActivity.java

DatabaseHelper mydb = new DatabaseHelper(this, "MyUsers", null, 1);

UserInfo userInfo = new UserInfo(tvUsername.getText().toString(), etEnterPassword.getText().toString());

            if (mydb.existingUsername(tvUsername.getText().toString()) == false) {
                mydb.insertTable(userInfo);
                Intent intent = new Intent(MainActivity.this, Lobby.class);
                intent.putExtra("username", userInfo.getUsername());
                startActivity(intent);
            } else {
                // some code
            }

DatabaseHelper.java

@Override
public void onCreate(SQLiteDatabase db) {
    db.execSQL("create table " + TABLE_NAME + "(" +
            COLUMN_ID + " integer primary key autoincrement, " +
            COLUMN_USERNAME + " text not null unique, " +
            COLUMN_PASSWORD + " text)");
}

// Method 1 (Commented out)
public ArrayList<UserInfo> existingUsername() {
    UserInfo userInfo;
    ArrayList<UserInfo> userArray = new ArrayList<UserInfo>();
    SQLiteDatabase db = this.getReadableDatabase();
    Cursor cursor = db.rawQuery("SELECT " + COLUMN_USERNAME + " FROM " + TABLE_NAME, null);
    cursor.moveToFirst();
    while (!cursor.isAfterLast()) {
        userInfo = new UserInfo(cursor.getString(cursor.getColumnIndex(COLUMN_USERNAME)));
        userArray.add(userInfo);
        cursor.moveToNext();
    }
    return userArray;
}

// Method 2 (Currently in use)
public boolean existingUsername(String username) {
    SQLiteDatabase db = this.getReadableDatabase();
    Cursor cursor = db.rawQuery("SELECT " + COLUMN_USERNAME + " FROM " + TABLE_NAME + " WHERE " + COLUMN_USERNAME + " = ?", new String[]{username});
    cursor.moveToFirst();
    while (!cursor.isAfterLast()) {

        if (cursor.getString(cursor.getColumnIndex(COLUMN_USERNAME)) == username) {
            return true;
        } else {
            cursor.moveToNext();
        }
    }
    return false;
}

预期结果:

我希望它检查数据库中是否存在我输入的“用户名”。如果否,请运行“ if”语句,然后转到下一个活动。如果是,请运行“ else”语句。

实际结果:

但是,事实证明代码将继续运行“ if”语句,并进行下一个活动,无论输入的用户名是否已存在于数据库中。如果输入的用户名已经存在于数据库中,则会在logcat中给我这个错误。

Logcat

019-06-01 14:06:19.774 27199-27199/com.karimun.myapplication E/SQLiteDatabase: Error inserting password=232323 username=Igor
android.database.sqlite.SQLiteConstraintException: UNIQUE constraint failed: users.username (code 2067 SQLITE_CONSTRAINT_UNIQUE)
    at android.database.sqlite.SQLiteConnection.nativeExecuteForLastInsertedRowId(Native Method)
    at android.database.sqlite.SQLiteConnection.executeForLastInsertedRowId(SQLiteConnection.java:796)
    at android.database.sqlite.SQLiteSession.executeForLastInsertedRowId(SQLiteSession.java:788)
    at android.database.sqlite.SQLiteStatement.executeInsert(SQLiteStatement.java:86)
    at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1564)
    at android.database.sqlite.SQLiteDatabase.insert(SQLiteDatabase.java:1433)
    at com.karimun.myapplication.DatabaseHelper.insertTable(DatabaseHelper.java:70)
    at com.karimun.myapplication.MainActivity$2.onClick(MainActivity.java:58)
    at android.view.View.performClick(View.java:6597)
    at android.view.View.performClickInternal(View.java:6574)
    at android.view.View.access$3100(View.java:778)
    at android.view.View$PerformClick.run(View.java:25885)
    at android.os.Handler.handleCallback(Handler.java:873)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:193)
    at android.app.ActivityThread.main(ActivityThread.java:6669)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)

3 个答案:

答案 0 :(得分:1)

您没有显示 insertTable(userInfo) 方法,但是如果您使用(假设您正在使用execSQL方法插入),则使用INSERT OR IGNORE而不是{{1} },那么重复项将被忽略。

但是,如果您改为使用insert方法(实际上使用INSERT或IGNORE)。它返回插入行的 rowid (长),如果未插入行,则返回-1。因此,检查返回值将告诉您由于某种原因(可能是重复项)未插入该行(因此无需进行预检查和相关的开销)。

  • 正如您使用INSERT定义ID列一样,该列是 rowid 列的别名(因此rowid的值将与ID列相同)。 / li>

以下是可能的代码,基于可以从可用代码中收集的内容。

integer primary key autoincrement
  • 请注意,因为它具有相同的名称和签名,所以必须替换现有方法或使用不同的名称。
  • 注意 getPassword 可能是从UserInfo获取密码值的错误方法

MainActivity.java中的代码可以是:-

public long insertTable(UserInfo userInfo) {

    ContentValues cv = new ContentValues();
    SQliteDatabase db = this.getWritableDatabase();
    cv.put(COLUMN_USERNAME,userInfo.getUserName());
    cv.put(COLUMN_PASSWORD,userInfo.getPassword());
    return db.insert(TABLE_NAME,null,cv);
}
  • 请注意,上面的代码是内部代码,由于尚未经过测试或运行,因此可能包含一些错误。

答案 1 :(得分:0)

比较有误

cursor.getString(cursor.getColumnIndex(COLUMN_USERNAME)) == username

即使用户名已经存在,这也会导致您的程序继续插入。

更改为equals()以进行正确的字符串比较。不要使用==来比较String(通常是对象)

username.equals(cursor.getString(cursor.getColumnIndex(COLUMN_USERNAME)))

如果username不为空

Objects.equals(username, cursor.getString(cursor.getColumnIndex(COLUMN_USERNAME)))

答案 2 :(得分:0)

您应该让SQL为您完成所有工作:

Select count(*) from sometable where username = @username

这将返回包含@username的记录数。如果数字为0,则表中不存在用户名。如果为1,则用户名存在并且是唯一的。如果大于1,则用户名存在并且不是唯一的。