【问题标题】:Table has no column named: SQLite odd behavior on insert表没有名为的列:插入时的 SQLite 奇怪行为
【发布时间】:2017-12-11 22:44:59
【问题描述】:

表没有名为的列:插入时的 SQLite 奇怪行为

我已经搜索并阅读了一些“表没有命名列”的条目,如下所示:

Android SQLite issue - table ... has no column named Table has no column named

但它们似乎并不适用,因为我的应用显示奇怪的“表 ___ 没有名为 ____(代码 1)的列:”错误,这取决于首先输入的内容。 宠物桌是:

public static final String SQL_CREATE =
        "CREATE TABLE " + TABLE_PETS + " (" +
                PET_ID + " INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE, " +
                VET_ID + " INTEGER, " +
                PET_NAME + " TEXT, " +
                " FOREIGN KEY(" + VET_ID + ") " +
                " REFERENCES vets(vetId) ON DELETE CASCADE);";

兽医表是:

public static final String SQL_CREATE =
        "CREATE TABLE " + TABLE_VETS + "(" +
                VET_ID + " INTEGER PRIMARY KEY UNIQUE, " +
                VET_NAME + " TEXT, " +
                ADDRESS1 + " TEXT, " +
                ADDRESS2 + " TEXT, " +
                CITY + " TEXT, " +
                STATE + " TEXT, " +
                ZIP_CODE + " TEXT, " +
                PHONE_NUMBER + " TEXT, " +
                EMAIL_ADDRESS + " TEXT);";

我检查了模拟器的数据库,结构如上图。我删除了应用程序的数据并卸载然后安装了应用程序。我输入宠物的名字:

public void addPetName(String name){
    Log.d(TAG, "Entered addPetName");
    try {
        db = this.getWritableDatabase();
        values.put(PET_NAME, name);
        db.insert(TABLE_PETS, null, values);
        Log.d(TAG, "Should have saved " + name + " to the DB");
        } catch (SQLException e) {
        e.printStackTrace();
    }
}

这是成功的(来自 LogCat):

DBHelper: Entered addPetName
DBHelper: Should have saved Tim to the DB

然后我尝试添加一个兽医名称:

public void addVetInfo(String name, String address1, String address2, String city, String state, String zip, String phone, String email){
    try {
        Log.d(TAG, "Entered addVetInfo");

        db = this.getWritableDatabase();
        Log.d(TAG, "Vet name entered is " + name);
        values.put(VET_NAME, name);
        Log.d(TAG, "Address1 entered is " + address1);
        values.put(ADDRESS1, address1);
        Log.d(TAG, "Address2 entered is " + address2);
        values.put(ADDRESS2, address2);
        Log.d(TAG, "City  entered is " + city);
        values.put(CITY, city);
        Log.d(TAG, "State entered is " + state);
        values.put(STATE, state);
        Log.d(TAG, "Zip entered is " + zip);
        values.put(ZIP_CODE, zip);
        Log.d(TAG, "Phone entered is " + phone);
        values.put(PHONE_NUMBER, phone);
        Log.d(TAG, "Email entered is " + email);
        values.put(EMAIL_ADDRESS, email);
        Log.d(TAG, "Add new vet data to table");
        db.insert(TABLE_VETS, null, values);
    } catch (SQLException e) {
        e.printStackTrace();
    }
}

这是不成功的(来自 LogCat):

SQLiteLog: (1) table vets has no column named petName
SQLiteDatabase: Error inserting zipCode= address2= city= address1= state=         
petName=Tig phoneNumber=null vetName=Springhill emailAddress=

android.database.sqlite.SQLiteException: table vets has no column named petName (code 1): , while compiling: INSERT INTO vets(zipCode,address2,city,address1,state,petName,phoneNumber,vetName,emailAddress) VALUES (?,?,?,?,?,?,?,?,?)

SQLite 中发生了一些事情,根据首先输入的数据阻止数据输入到表中:

  • 先输入宠物名字,输入宠物名字失败。正如 vet 表 中所见,没有 petName
  • 先输入宠物名字,输入宠物名字失败。如宠物桌所示 没有 zipCode

SQLite 会发生什么?可能是因为我没有打开/关闭数据库连接吗?

【问题讨论】:

  • addPetnameaddVetInfo 中,在db = this.getWritableDatabase(); 之后添加ContentValues values = new Contentvalues(); 即问题可能正在重复使用values
  • 我认为你没有刷新你的 ContentValues 尝试将它添加到你的每个函数 values = new ContentValues()
  • 迈克 T 和杰罗尔,你们是天才!我已经声明了所有方法都可以使用它的值,这确实是我的问题。您建议在每个方法内部声明它可以解决问题。我不认为这些值会被重用。我添加了 LogCat 输出,并看到新输入被附加到之前添加的所有输入中。谢谢!

标签: android database sqlite


【解决方案1】:

您的问题很可能是您正在重复使用 ContentValues values 的相同实例,从而添加到它。所以基本上第一次使用会起作用,但后续使用可能会出现问题。

解决方案是在为每种方法添加(放置)值之前使用values.clear()。或者为每个例如使用一个新的 ContentValues 实例使用ContentValues values = new ContentValues();

后者是更常见的方法。

例如,addPetname 方法可以是:-

public void addPetName(String name){
    Log.d(TAG, "Entered addPetName");
    try {
        db = this.getWritableDatabase();
        ContentValues values = new ContentValues(); //<<<<<<<<
        values.put(PET_NAME, name);
        db.insert(TABLE_PETS, null, values);
        Log.d(TAG, "Should have saved " + name + " to the DB");
        } catch (SQLException e) {
        e.printStackTrace();
    }
}

public void addPetName(String name){
    Log.d(TAG, "Entered addPetName");
    try {
        db = this.getWritableDatabase();
        values.clear(); //<<<<<<<<
        values.put(PET_NAME, name);
        db.insert(TABLE_PETS, null, values);
        Log.d(TAG, "Should have saved " + name + " to the DB");
        } catch (SQLException e) {
        e.printStackTrace();
    }
}

【讨论】:

  • 是的,就是这样。正如我在上面对您的评论中所指出的那样,我只是没有想到“值”会继续附加值这一事实,添加 LogCat 输出显示了这种价值增长。你所展示的是一个伟大的教训!感谢您的帮助。
  • 另外两件事:1) 出于某种原因,我不知道为什么,我应该通过 LogCat 验证 values 中的内容是 values.put() 的结果,但没有(b) 关于 ContantValues 的 put() 方法的描述,并没有真正理解“向集合添加值”的后果。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-09-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-06
  • 1970-01-01
相关资源
最近更新 更多