繁体   English   中英

当我尝试在SQLite数据库的表中创建三个以上的列时,为什么出现错误提示列不存在?

[英]Why am I getting errors saying column doesn't exist when I try to create more than three columns in a table in SQLite database?

这是我的代码。 我收到一条错误消息,说表用户没有名为street的列。

SQLiteDatabase database = this.openOrCreateDatabase("ee",MODE_PRIVATE,null);
database.execSQL("CREATE TABLE IF NOT EXISTS users (name VARCHAR, age INT(3),id INT(3),house VARCHAR,street VARCHAR)");
database.execSQL("INSERT INTO users (name,age,id,house,street) VALUES ('ROB',34,33,'home','street')");
Cursor c = database.rawQuery("SELECT * FROM users",null);
int nameIndex = c.getColumnIndex("name");
int ageIndex = c.getColumnIndex("age");
int idIndex = c.getColumnIndex("id");
int houseIndex = c.getColumnIndex("house");
int streetIndex = c.getColumnIndex("street");

c.moveToFirst();
while (c!=null){
    Log.i("Name",c.getString(nameIndex));
    Log.i("Age",Integer.toString(c.getInt(ageIndex)));
    Log.i("id",Integer.toString(c.getInt(idIndex)));
    Log.i("house",c.getString(houseIndex));
    Log.i("street",c.getString(streetIndex));

    c.moveToNext();
}

该消息清楚地表明街道列不存在。 CREATE SQL没什么错,因此自从最初创建表以来,很可能已经修改了该语句,在这种情况下, IF NOT EXISTS导致不执行表创建(无论如何都会失败,因为该表存在)。

如果您没有需要保留的数据,那么最简单的解决方法是删除应用程序的数据或卸载应用程序并重新运行。

我可以确认您的代码是否正确(请参阅注释),并且在执行上述操作后产生/结果为:-

03-31 20:47:12.442 1142-1142/? I/Name: ROB
03-31 20:47:12.442 1142-1142/? I/Age: 34
03-31 20:47:12.442 1142-1142/? I/id: 33
03-31 20:47:12.442 1142-1142/? I/house: home
03-31 20:47:12.442 1142-1142/? I/street: street
  • 请注意,此后您的应用程序将崩溃,因为您不正确地尝试遍历游标。 参见下面的修复。

如果确实有需要保留的数据,则可以使用:-

SQLiteDatabase database = this.openOrCreateDatabase("ee",MODE_PRIVATE,null);
database.execSQL("CREATE TABLE IF NOT EXISTS users (name VARCHAR, age INT(3),id INT(3),house VARCHAR,street VARCHAR)");
database.execSQL("ALTER TABLE users ADD COLUMN street VARCHAR"); //<<<< ADDED
database.execSQL("INSERT INTO users (name,age,id,house,street) VALUES ('ROB',34,33,'home','street')");
....... rest of your code

}

但是,如果再次使用以上方法,则将失败,因为该列将存在。 因此,第一次运行后应删除添加行。

游标遍历修复

在获取游标后的代码中,使用moveToFirst移至第一行,然后检查游标是否为空。

这很容易失败,因为从SQLiteDatabase方法返回的Cursor永远不会为null。 这是无用的检查。 如果Cursor没有行,那么它将有一个计数(Cursor的getCount方法返回一个带有行数的整数,可以为0)。相反,您应该检查moveToFirst的返回值,如果移至可以进行第一行,如果没有行,则返回false。

您可以使用if (c.moveToFirst()) { .... do your stuff }

您还具有未选中的moveToNext ,如果可以进行其他移动,则再次返回true,否则返回false。 因此,如果在第一行之后有1行,则会失败android.database.CursorIndexOutOfBoundsException: Index 1 requested, with a size of 1 这是因为当循环的下一次迭代发生时,行int nameIndex = c.getColumnIndex("name"); 当第二行不存在时,试图获取第二行(第一行为索引0)。

  • 即消息是说您正在尝试访问只有第二行的第二行。

我建议更换:-

c.moveToFirst();
while (c!=null){
    Log.i("Name",c.getString(nameIndex));
    Log.i("Age",Integer.toString(c.getInt(ageIndex)));
    Log.i("id",Integer.toString(c.getInt(idIndex)));
    Log.i("house",c.getString(houseIndex));
    Log.i("street",c.getString(streetIndex));

    c.moveToNext();
}

while (c.moveToNext())
    Log.i("Name",c.getString(nameIndex));
    Log.i("Age",Integer.toString(c.getInt(ageIndex)));
    Log.i("id",Integer.toString(c.getInt(idIndex)));
    Log.i("house",c.getString(houseIndex));
    Log.i("street",c.getString(streetIndex));
}

注意

  • 按照目前的情况,您的代码将在每次运行时向数据库添加一个具有相同数据的新行,例如,第二次运行的输出将是:

    03-31 21:12:01.635 1279-1279/? I/Name: ROB 03-31 21:12:01.635 1279-1279/? I/Age: 34 03-31 21:12:01.635 1279-1279/? I/id: 33 03-31 21:12:01.635 1279-1279/? I/house: home 03-31 21:12:01.635 1279-1279/? I/street: street 03-31 21:12:01.635 1279-1279/? I/Name: ROB 03-31 21:12:01.635 1279-1279/? I/Age: 34 03-31 21:12:01.635 1279-1279/? I/id: 33 03-31 21:12:01.635 1279-1279/? I/house: home 03-31 21:12:01.635 1279-1279/? I/street: street

认为如果没有适当的堆栈跟踪,很难在这里猜测错误。 但是,我认为问题是在添加street列之后没有重新创建表。 我认为初始表仅包含四列,分别是name, age, id, house 然后添加了street列。 但是,由于create table命令包含CREATE TABLE IF NOT EXISTS ,因此不再创建该表。

因此,我建议您在设备中卸载当前版本的应用程序后,重新安装,然后检查是否发生相同的错误。

但是,如果您使用SQLiteOpenHelper打开数据库,则可能会考虑以其他方式进行操作,这将不需要卸载应用程序。 只需将表放在onUpgrade函数中,然后每次在设备中运行该应用程序时,只需更新数据库版本,即可删除以前的数据库表,它的作用就像一个新的数据库表。

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    db.execSQL("DROP table users");   
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM