执行调用db.delete时如何修复“无法识别的令牌”

时间:2019-10-16 14:32:58

标签: android android-sqlite

我使用SQLite存储和检索Android应用程序的数据。我创建了一个方法,该方法通过删除条目的主键(即UUID)来删除表中的条目。但是,当我调用.delete命令时,我得到的是未重新分类的令牌。

(当前思维方式)数据库期望使用c.getId()来指向要删除的条目的字符串,该字符串将返回UUID而不是字符串。但是我不确定如何转换它,或者它可能是表达式中的语法问题。

// CheckInList.java

public class CheckInList {
    private static CheckInList sCheckInList;
    private Context mContext;
    public SQLiteDatabase mDataBase;
...
//PROBLEM METHOD v
public void deleteCheckIn(CheckIn c) {
        mDataBase.delete(DATABASE_NAME,  CheckInTable.Cols.UUID + "=" + c.getId(), null);
    }
...

/// CheckInBaseHelper

public class CheckInBaseHelper extends SQLiteOpenHelper {
    private static final int VERSION = 1;
    public static final String DATABASE_NAME = "checkinBase.db";

    public CheckInBaseHelper(Context context) {
        super(context, DATABASE_NAME, null, VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL("create TABLE " + CheckInTable.NAME + "(" +
                " _id integer primary key autoincrement, " +
                CheckInTable.Cols.UUID + ", " +
                CheckInTable.Cols.TITLE + ", " +
                CheckInTable.Cols.PLACE + ", " +
                CheckInTable.Cols.DETAILS + ", " +
                CheckInTable.Cols.DATE + ", " +
                CheckInTable.Cols.LATITUDE + ", " +
                CheckInTable.Cols.LONGITUDE +
                ")"
        );
    }

/// CheckInCursorWrapper

public class CheckInCursorWrapper extends CursorWrapper {
    public CheckInCursorWrapper(Cursor cursor) {
        super(cursor);
    }

    public CheckIn getCheckIn() {
        String uuidString = getString(getColumnIndex(CheckInTable.Cols.UUID));
        String title = getString(getColumnIndex(CheckInTable.Cols.TITLE));
        String place = getString(getColumnIndex(CheckInTable.Cols.PLACE));
        String details = getString(getColumnIndex(CheckInTable.Cols.DETAILS));
        long date = getInt(getColumnIndex(CheckInTable.Cols.DATE));
        Double latitude = getDouble(getColumnIndex(CheckInTable.Cols.LATITUDE));
        Double longitude = getDouble(getColumnIndex(CheckInTable.Cols.LONGITUDE));

        CheckIn checkin = new CheckIn(UUID.fromString(uuidString));
        checkin.setTitle(title);
        checkin.setPlace(place);
        checkin.setDetails(details);
        checkin.setDate(new Date(date));
        checkin.setLatitude(latitude);
        checkin.setLongitude(longitude);

        return checkin;
    }
}

该方法旨在通过标识每个条目的ID来从数据库中删除签入。

SQLiteException:unrecognized token: "7ac5"

android.database.sqlite.SQLiteException: unrecognized token: "7ac5" (code 1 SQLITE_ERROR): , while compiling: DELETE FROM checkinBase.db WHERE uuid=d21a141d-7ac5-487b-a5af-6eae0825ac37

1 个答案:

答案 0 :(得分:0)

除了无法识别的令牌问题外,您还将遇到另一个问题。问题是:-

  • a)您从一个表中删除了不是数据库,该数据库可能会(具有)多个表。

  • b)您需要将字符串用单引号引起来,即使用uuid ='d21a141d-7ac5-487b-a5af-6eae0825ac37'。您可以将...... + "=" + c.getId()更改为...... + "='" + c.getId() + "'"

但是,建议对值进行绑定(通常使用 ? 占位符),该占位符将替换为值,并适当地将其括起来(例如,添加单引号) ),从而防止SQL注入。

一个完整的解决方法是更改​​:-

public void deleteCheckIn(CheckIn c) {
    mDataBase.delete(DATABASE_NAME,  CheckInTable.Cols.UUID + "=" + c.getId(), null);
}

public int deleteCheckIn(CheckIn c) {
    return mDataBase.delete(CheckInTable.NAME,  CheckInTable.Cols.UUID + "=?", new String[]{c.getId()});
}

以上将:-

  • 使用表而不是数据库,从而消除了即将发生的表未找到异常。
  • 更正无法识别的令牌。
  • 防止SQL注入。
  • 返回已删除的行数,这可能有助于了解(例如,如果0没有删除任何行)。