【问题标题】:Multiple Tables on Android DB - no such tableAndroid DB 上的多个表 - 没有这样的表
【发布时间】:2013-04-11 04:52:44
【问题描述】:

有一个奇怪的问题,这似乎很常见,但我无法找到合适的解决方案。也许你们可以帮我弄清楚我哪里出错了。

这是我的通用数据库适配器类

package com.example.mobilebillforecaster;

import android.content.Context;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class CommonDBclass {

public static final String DATABASE_NAME = "mbfDB";

public static final int DATABASE_VERSION = 1;

public static final String CREATE_ETI_TABLE =

"CREATE TABLE etisalatdb (_id INTEGER PRIMARY KEY AUTOINCREMENT, "
        + EtiTariffDB.KEY_ROWID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
        + EtiTariffDB.KEY_PACKNAME + " TEXT, " + EtiTariffDB.KEY_PACKRENT
        + " INTEGER, " + EtiTariffDB.KEY_SIMRATE + " INTEGER, "
        + EtiTariffDB.KEY_NATMINSBUN + " INTEGER, "
        + EtiTariffDB.KEY_NATMINSRATE + " INTEGER, "
        + EtiTariffDB.KEY_INTMINSBUN + " INTEGER, "
        + EtiTariffDB.KEY_INTMINSRATE + " INTEGER, "
        + EtiTariffDB.KEY_NATSMSBUN + " INTEGER, "
        + EtiTariffDB.KEY_NATSMSRATE + " INTEGER, "
        + EtiTariffDB.KEY_INTSMSBUN + " INTEGER, "
        + EtiTariffDB.KEY_INTSMSRATE + " INTEGER, "
        + EtiTariffDB.KEY_MMSBUN + " INTEGER, " + EtiTariffDB.KEY_MMSRATE
        + " INTEGER, " + EtiTariffDB.KEY_DATALBUN + " INTEGER, "
        + EtiTariffDB.KEY_DATALRATE + " INTEGER" + ");";

public static final String CREATE_DU_TABLE =

"CREATE TABLE dudatabase(_id INTEGER PRIMARY KEY AUTOINCREMENT, "
        + DuTariffDB.KEY_PACKNAME + " TEXT, " + DuTariffDB.KEY_PACKRENT
        + " INTEGER, " + DuTariffDB.KEY_NATMINSRATE + " INTEGER, "
        + DuTariffDB.KEY_NATMOBRATE + " INTEGER, "
        + DuTariffDB.KEY_INTMINSRATE + " INTEGER, "
        + DuTariffDB.KEY_NATSMSRATE + " INTEGER, "
        + DuTariffDB.KEY_INTSMSRATE + " INTEGER, "
        + DuTariffDB.KEY_DATALBUN + " INTEGER, " + DuTariffDB.KEY_DATALRATE
        + " INTEGER" + ");";

private final Context context;
private DatabaseHelper DBHelper;
private SQLiteDatabase db;

public CommonDBclass(Context ctx) {
    this.context = ctx;
    this.DBHelper = new DatabaseHelper(this.context);
}

private static class DatabaseHelper extends SQLiteOpenHelper {
    DatabaseHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(CREATE_ETI_TABLE);
        db.execSQL(CREATE_DU_TABLE);

    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    }
}

public CommonDBclass open() throws SQLException {
    this.db = this.DBHelper.getWritableDatabase();

    return this;
}

public void close() {
    this.DBHelper.close();
}

}

这是我的适配器之一

package com.example.mobilebillforecaster;

import java.util.ArrayList;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class EtiTariffDB {

public static final String KEY_ROWID = "_id";
public static final String KEY_PACKNAME = "pack_name";
public static final String KEY_PACKRENT = "pack_rent";
public static final String KEY_SIMRATE = "sim_rate";
public static final String KEY_NATMINSBUN = "natmins_bun";
public static final String KEY_NATMINSRATE = "natmins_rate";
public static final String KEY_INTMINSBUN = "intmins_bun";
public static final String KEY_INTMINSRATE = "intmins_rate";
public static final String KEY_NATSMSBUN = "natsms_bun";
public static final String KEY_NATSMSRATE = "natsms_rate";
public static final String KEY_INTSMSBUN = "intsms_bun";
public static final String KEY_INTSMSRATE = "intsms_rate";
public static final String KEY_MMSBUN = "mms_bun";
public static final String KEY_MMSRATE = "mms_rate";
public static final String KEY_DATALBUN = "datal_bun";
public static final String KEY_DATALRATE = "datal_rate";

private static final String DATABASE_TABLE = "etitarifftable";

private DbHelper ourHelper;
private final Context cctext;

private SQLiteDatabase ourDatabase;

private static class DbHelper extends SQLiteOpenHelper {

    DbHelper(Context ourContext) {
        super(ourContext, CommonDBclass.DATABASE_NAME, null,
                CommonDBclass.DATABASE_VERSION);

    }

    @Override
    public void onCreate(SQLiteDatabase db) {

    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // TODO Auto-generated method stub

    }

}

public EtiTariffDB(Context ctx) {
    this.cctext = ctx;

}

public EtiTariffDB open() {
    this.ourHelper = new DbHelper(this.cctext);
    this.ourDatabase = this.ourHelper.getWritableDatabase();
    return this;
}

public void close() {
    this.ourHelper.close();
}

public long createEtiTariff(String packname, String packrent,
        String simrent, String natbun, String natrate, String intbundle,
        String intrate, String natsmsbun, String natsmsrate,
        String intsmsbun, String intsmsrate, String mmsbun, String mmsrate,
        String datalbun, String datalrate) {
    ContentValues cv = new ContentValues();
    cv.put(KEY_PACKNAME, packname);
    cv.put(KEY_PACKRENT, packrent);
    cv.put(KEY_SIMRATE, simrent);
    cv.put(KEY_NATMINSBUN, natbun);
    cv.put(KEY_NATMINSRATE, natrate);
    cv.put(KEY_INTMINSBUN, intbundle);
    cv.put(KEY_INTMINSRATE, intrate);
    cv.put(KEY_NATSMSBUN, natsmsbun);
    cv.put(KEY_NATSMSRATE, natsmsrate);
    cv.put(KEY_INTSMSBUN, intsmsbun);
    cv.put(KEY_INTSMSRATE, intsmsrate);
    cv.put(KEY_MMSBUN, mmsbun);
    cv.put(KEY_MMSRATE, mmsrate);
    cv.put(KEY_DATALBUN, datalbun);
    cv.put(KEY_DATALRATE, datalrate);

    return this.ourDatabase.insert(DATABASE_TABLE, null, cv);

}

这是我调用数据库的 java 文件的一部分

    EtiTariffDB etisalatDB = new EtiTariffDB(this);

    etisalatDB.open();

    etisalatDB.createEtiTariff(etipackname, etipackrent, etisimrent,
            etinatbun, etinatrate, etiintbundle, etiintrate,
            etinatsmsbundle, etinatsmsrate, etiintsmsbundle,
                            etiintsmsrate,etimmsbundle, etimmsrate, 
                            etidatalocalbundle, etidatalocalrate);

    etisalatDB.close();

我得到的错误是:

04-10 20:17:47.958: E/SQLiteLog(30526): (1) no such table: etitarifftable
04-10 20:17:48.078: E/SQLiteDatabase(30526): Error inserting natmins_rate=0.30 pack_name=Corporate package natsms_bun=200 mms_rate=0.45 mms_bun=- intsms_rate=0.60 natsms_rate=0.18 intsms_bun=- sim_rate=29 intmins_bun=100 datal_rate=0.1 datal_bun=2000 intmins_rate=1.10 natmins_bun=100 pack_rent=249
04-10 20:17:48.078: E/SQLiteDatabase(30526): android.database.sqlite.SQLiteException: no such table: etitarifftable (code 1): , while compiling: INSERT INTO etitarifftable(natmins_rate,pack_name,natsms_bun,mms_rate,mms_bun,intsms_rate,natsms_rate,intsms_bun,sim_rate,intmins_bun,datal_rate,datal_bun,intmins_rate,natmins_bun,pack_rent) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)

我已经阅读了许多帖子并浏览了许多论坛。在这里可以找到我用来创建它的示例:

Multiple Table SQLite DB Adapter(s) in Android?

我已经检查并重新检查了我的编码。我怀疑我没有在 create 方法上调用 commonDBclass,但我不知道如何。请帮忙。

谢谢。

【问题讨论】:

  • 如果您之后添加了表,您需要增加数据库版本并实现 onUpgrade(...) 以便创建新表。
  • 您似乎没有创建名为etitarifftable 的表。只有etisalatdbdudatabase。会不会是这个原因?
  • 即使我删除了整个数据库?我尝试了 onupgrade 和版本,没有任何反应。所以我删除了数据库并尝试了..同样的问题。创建了数据库但没有表。
  • 我将表名指定为 etitarifftable。即使没有创建表,我至少应该正确创建 etisalatdb 和 dudatabase 表?这也不存在:(

标签: android sqlite multiple-tables


【解决方案1】:

我马上注意到了一些问题:

  1. 您根本没有字符串来创建名为etitarifftable 的表。
  2. 您没有执行您的CREATE TABLE 字符串。
  3. 您正在更改 Java 代码,但没有告诉 SQLiteOpenHelper 更新 SQL 架构。
  4. 表只能有一个主键

简单的解决方案:

  1. 要么创建etitarifftable,要么在查询中使用适当的表名。
  2. 将适当的execSQL() 语句添加到DbHelper#onCreate()

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(CREATE_ETI_TABLE);
        db.execSQL(CREATE_DU_TABLE);
    }
    
  3. 增加DATABASE_VERSION,这将调用onUpgrade()onUpgrade() 最基本的形式应该是这样的:

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("DROP TABLE IF EXISTS etisalatdb");
        db.execSQL("DROP TABLE IF EXISTS dudatabase");
        onCreate(db);
    }
    
  4. 从两个表中删除一个主键声明:

    "CREATE TABLE etisalatdb (EtiTariffDB.KEY_ROWID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + ...
    

最后,我感觉还有更多错误,但您的 LogCat 会引导您找到它们。 (另外我不确定你为什么有两个不同的适配器......)

【讨论】:

  • 嗨,Sam,感谢您的详细帖子。关于第 2 点,您已经列出它应该在我的 EtiTariffDB 类中的 DBhelper#oncreate() 下。但是,当我添加 execSQL 行时,它会尝试创建变量(例如:CREATE_ETI_TABLE),因为这是在 commonDBclass 文件中定义的变量。
  • 对不起,当我写这一步时,我没有意识到你创建了两个 SQLiteOpenHelper... 因为DbHelper 只调用super(ourContext, CommonDBclass.DATABASE_NAME, null, CommonDBclass.DATABASE_VERSION); DatabaseHelper 的信息,你可能可以删除DbHelper
  • 嗨。我不应该为 EtiTariffDB 定义一个助手吗?如果我删除 DBhelper,所有方法都不会停止运行吗?
  • 我假设您希望 CommonDBclass 拥有数据库适配器的通用代码,因此 EtiTariffDB 应该扩展 CommonDBclass 并使用通用方法,例如 SQLiteOpenHelper。
  • 嗨,Sam,你能给我一个它应该是什么样子的样本吗?我对此并不感到抱歉。感谢您的帮助。
【解决方案2】:

您需要在插入记录之前创建表,您可以通过以下方式执行此操作:

class DbHelper  extends SQLiteOpenHelper {
    ...

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL("CREATE TABLE " + DATABASE_TABLE + " {definition} ");
    }

    ...
}

看起来根本不像你打电话给CommonDBclass。我认为你需要重新思考和重组你做这件事的方式。 EtiTariffDB 不应该是“数据库”,它是一个表,您应该将其视为一个表。使用 CommonDBclass 获取 EtiTariff 表对象,而不是相反。然后您可以执行以下操作:

DatabaseHelper db = new DatabaseHelper();
EtiTariffTable etiTariff = db.getEtiTariffTable();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-17
    • 1970-01-01
    • 1970-01-01
    • 2019-01-23
    • 2012-04-12
    • 1970-01-01
    相关资源
    最近更新 更多