我已经在我的SQLiteOpenHelper onCreate()中创建了我的表
SQLiteException: no such table
or
SQLiteException: no such column
错误。为什么?
注意: (这是每周数十个类似问题的汇总。试图在这里提供一个“规范的”社区wiki问题/答案,以便所有这些问题都可以指向一个很好的参考。)
我已经在我的SQLiteOpenHelper onCreate()中创建了我的表
SQLiteException: no such table
or
SQLiteException: no such column
错误。为什么?
注意: (这是每周数十个类似问题的汇总。试图在这里提供一个“规范的”社区wiki问题/答案,以便所有这些问题都可以指向一个很好的参考。)
当前回答
Sqlite数据库覆盖两种方法
1) onCreate (): 该方法仅在应用程序第一次启动时调用一次。所以它只调用一次
2) onUpgrade () 当我们改变数据库版本时,这个方法被调用,然后这个方法被调用。它用于改变表结构,如在创建DB Schema后添加新列
其他回答
没有这样的表,主要是当你没有打开SQLiteOpenHelper类与getwritabledata(),在此之前,你还必须调用make构造函数与databasename & version。 当SQLiteOpenHelper类中给出的版本号中有升级值时,OnUpgrade将被调用。
下面是代码片段(没有找到这样的列可能是因为列名中的拼写):
public class database_db {
entry_data endb;
String file_name="Record.db";
SQLiteDatabase sq;
public database_db(Context c)
{
endb=new entry_data(c, file_name, null, 8);
}
public database_db open()
{
sq=endb.getWritableDatabase();
return this;
}
public Cursor getdata(String table)
{
return sq.query(table, null, null, null, null, null, null);
}
public long insert_data(String table,ContentValues value)
{
return sq.insert(table, null, value);
}
public void close()
{
sq.close();
}
public void delete(String table)
{
sq.delete(table,null,null);
}
}
class entry_data extends SQLiteOpenHelper
{
public entry_data(Context context, String name, SQLiteDatabase.CursorFactory factory,
int version) {
super(context, name, factory, version);
// TODO Auto-generated constructor stub
}
@Override
public void onCreate(SQLiteDatabase sqdb) {
// TODO Auto-generated method stub
sqdb.execSQL("CREATE TABLE IF NOT EXISTS 'YOUR_TABLE_NAME'(Column_1 text not null,Column_2 text not null);");
}
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
onCreate(db);
}
}
当需要创建表时,第一次调用onCreate。我们需要重写这个方法,在这里我们编写了由SQLiteDatabase执行的表创建脚本。execSQL方法。在第一次部署中执行后,此方法将不再被调用。
onUpgrade 当数据库版本升级时调用此方法。假设第一次部署时,数据库版本为1,在第二次部署时,数据库结构发生了变化,例如在表中增加了额外的列。假设数据库版本现在是2。
在我的例子中,我从XML-file中获取带有<string-array>的项,其中存储<item>s。在这些<item>s我持有SQL字符串和应用databaseBuilder.addMigrations(迁移)一个接一个。我犯了一个错误,忘记在引用前添加\,得到了异常:
android.database.sqlite.SQLiteException:没有这样的列:some_value(代码1 SQLITE_ERROR):,而编译:INSERT INTO table_name(id, name) VALUES(1, some_value)
所以,这是一个正确的变体:
<item>
INSERT INTO table_name(id, name) VALUES(1, \"some_value\")
</item>
根据Jaskey的要求,进一步补充这里的缺失点
数据库版本存储在SQLite数据库文件中。
Catch是构造函数
SQLiteOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version)
因此,当使用名称(第2个参数)调用数据库helper构造函数时,平台检查数据库是否存在,如果数据库存在,它从数据库文件头中获取版本信息并触发正确的回调
正如在旧的回答中已经解释的那样,如果具有该名称的数据库不存在,则会触发onCreate。
下面用一个例子解释onUpgrade的情况。
比方说,你的第一个版本的应用程序有DatabaseHelper(扩展SQLiteOpenHelper),构造函数将version传递为1,然后你提供了一个升级的应用程序,新的源代码将version传递为2,然后当DatabaseHelper被构造时,平台会自动看到文件已经存在,但版本低于你传递的当前版本,从而触发onUpgrade。
现在,假设您计划提供一个db version为3的应用程序的第三个版本(只有当数据库模式要修改时,db version才会增加)。在这种增量升级中,您必须从每个版本增量地编写升级逻辑,以获得更好的可维护代码
下面是伪代码示例:
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
switch(oldVersion) {
case 1:
//upgrade logic from version 1 to 2
case 2:
//upgrade logic from version 2 to 3
case 3:
//upgrade logic from version 3 to 4
break;
default:
throw new IllegalStateException(
"onUpgrade() with unknown oldVersion " + oldVersion);
}
}
注意情况1和2中缺少break语句。这就是我所说的增量升级。
假设旧版本是2,新版本是4,那么逻辑将把数据库从2升级到3,然后再升级到4
如果旧版本是3,新版本是4,它将只运行3到4的升级逻辑
您可以创建数据库和表
public class DbHelper extends SQLiteOpenHelper {
private static final String DBNAME = "testdatbase.db";
private static final int VERSION = 1;
public DbHelper(Context context) {
super(context, DBNAME, null, VERSION);
// TODO Auto-generated constructor stub
}
@Override
public void onCreate(SQLiteDatabase db) {
// TODO Auto-generated method stub
db.execSQL("create table BookDb(id integer primary key autoincrement,BookName text,Author text,IssuedOn text,DueDate text,Fine text,Totalfine text");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS BookDb");
onCreate(db);
}
}
注意:如果您想创建另一个表或添加列或没有这样的表,只需增加VERSION