Android 在SQLite中重新创建表

Android 在SQLite中重新创建表,android,database,sqlite,Android,Database,Sqlite,在实现数据库的save-/loadfunction时,我删除了这些表,以查看我的应用程序是否可以在必要时处理表的创建—当然,它不能 所以在我的testactivity的onCreate中,我创建了一个DB实例,它在它的构造函数中创建了一个DBOpenHelper实例。 基本上,当DBOpenHelper实例调用getWritableDatabase()时,应该执行DBOpenHelper的onCreate,在我的数据库中创建表。 我认为问题在于,getWritableDatabase()没有被调

在实现数据库的save-/loadfunction时,我删除了这些表,以查看我的应用程序是否可以在必要时处理表的创建—当然,它不能

所以在我的testactivity的onCreate中,我创建了一个DB实例,它在它的构造函数中创建了一个DBOpenHelper实例。 基本上,当DBOpenHelper实例调用getWritableDatabase()时,应该执行DBOpenHelper的onCreate,在我的数据库中创建表。 我认为问题在于,getWritableDatabase()没有被调用,因为数据库本身已经存在——我想我读过类似这样的东西,它吸收了openOrCreateDatabase的功能

如何确保在不存在表的情况下重新创建表,而无需每次删除和重新创建数据库

DBOpenhelper:

public class DBOpenHelper extends SQLiteOpenHelper {

public static final int DATABASE_VERSION = 1;
public static String DATABASE_NAME = "RTDB";
public static final String DB_TABLE_NAME1 = "playertable";
public static final String DB_TABLE_NAME2 = "itemtable";
public static String TAG = "openhelper";
private static final String DB_CREATE_TABLE_PT = "CREATE TABLE IF NOT EXISTS "
        + DB_TABLE_NAME1
        + " ("
        + "ID INT(2) PRIMARY KEY AUTOINCREMENT,"
        + "Name VARCHAR(30) ,"
        + "HP INT(3) ,"
        + "Satisfaction INT(3) ,"
        + "Hygiene INT(1) , " + "IsAlive INT(1) " + " )";

private static final String DB_CREATE_TABLE_IT = "CREATE TABLE IF NOT EXISTS "
        + DB_TABLE_NAME2
        + " ("
        + "Money INT(3) ,"
        + "Gas INT(3) ,"
        + "Food INT(3) ,"
        + "Toiletries INT(3) ,"
        + "Spareparts INT(3) ,"
        + "Meds INT(3) ,"
        + "Tents INT(3) ,"
        + "Ration INT(1) ,"
        + "Trabbihp INT(3) ," + "Trabbispeed INT(2)" + " )";

public DBOpenHelper(Context context, String databaseName) {
    super(context, databaseName, null, DATABASE_VERSION);
}

@Override
public void onCreate(SQLiteDatabase db) {
    Log.d("TAG", "PT :" + DB_CREATE_TABLE_PT);
    db.execSQL(DB_CREATE_TABLE_PT);
    Log.d(TAG, "PT create" + DB_CREATE_TABLE_PT);
    db.execSQL(DB_CREATE_TABLE_IT);
    Log.d(TAG, "IT create" + DB_CREATE_TABLE_IT);
}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    db.execSQL("DROP TABLE IF EXISTS " + DB_TABLE_NAME1);
    db.execSQL("DROP TABLE IF EXISTS " + DB_TABLE_NAME2);
    onCreate(db);
}

}
DB:


不确定您对
getWritableDatabase
功能的描述是否正确:查看您的代码,您似乎做了正确的事情,因为我在许多部署的应用程序中使用了非常类似的结构,没有任何错误。它正确地处理所有表的创建/升级,而不管它们是否存在或数据库是否存在。您可能想尝试将
DBOpenHelper
设置为一个静态类:这对我来说很有用。或者仔细检查您的日志:如果发生了一些其他异常,乍一看可能并不相关,那么这可能会为您指明解决方案


编辑:尝试
私有静态类DBOpenHelper扩展SQLiteOpenHelper
。我还建议更改数据库版本,强制调用
onUpgrade
方法。通常情况下,如果删除了表,但文件存在,则需要调用信息架构来检查数据库文件是否定义了表
onCreate
仅在文件不存在时调用,而
onUpdate
仅在更改数据库版本时调用


编辑:有关使用信息架构表检查表是否存在的更多详细信息,请参阅。您只需对SQLITE_主表运行查询,如果找不到特定的表,则运行CREATE语句。

Logcat报告的所有内容都与未创建表有关。还尝试将DBOpenHelper设置为静态类,但我得到一个错误,即这是一个非法的修饰符“通常情况下,如果您删除了表,但文件存在,则需要调用信息架构来检查数据库文件是否定义了表。”你能再解释一下吗?如何处理没有表的现有数据库的情况?
public class DB {

private Context context;
private SQLiteDatabase db;
private static String TAG = "save";
private static ContentValues itemValues = new ContentValues();
private static ContentValues playerValues = new ContentValues();

public DB(Context context) {
    this.context = context;
    DBOpenHelper dbHelper = new DBOpenHelper(this.context, "RTDB");
    this.db = dbHelper.getWritableDatabase();
}

public void savePlayer(Player player[]) {

    for (int i = 0; i <= 3; i++) {

        playerValues.put("Name", player[i].getName());
        playerValues.put("HP", player[i].getHp());
        playerValues.put("Satisfaction", player[i].getsatisfaction());
        playerValues.put("Hygiene", player[i].isHygieneInt());
        playerValues.put("IsAlive", player[i].isAliveInt());

    }
    db.insert("playertable", null, playerValues);
}

// Speichern der Items
// TODO Position fehlt noch
public void saveItems() {
    itemValues.put("Money", Resource.money);
    itemValues.put("Gas", Resource.gas);
    itemValues.put("Food", Resource.food);
    itemValues.put("Toiletries", Resource.toiletries);
    itemValues.put("Spareparts", Resource.spareparts);
    itemValues.put("Meds", Resource.meds);
    itemValues.put("Tents", Resource.tents);
    itemValues.put("Ration", Resource.ration);
    itemValues.put("Trabbihp", Resource.trabbihp);
    itemValues.put("Trabbispeed", Resource.trabbispeed);

    db.insert("itemtable", null, itemValues);
}

// Hier werden die Items aus der Datenbank abgefragt, der zurueckgelieferte
// Cursor vie cursorToIntArray() in einen Int Array umgewandelt und dessen
// Inhalt in die Ressource Klasse geschrieben
public void loadItems() {
    Cursor itemCursor = db.query("itemtable", null, null, null, null, null,
            null);
    int[] itemIntArray = cursorToInt(itemCursor, 9);

    Resource.money = itemIntArray[0];
    Resource.gas = itemIntArray[1];
    Resource.food = itemIntArray[2];
    Resource.toiletries = itemIntArray[3];
    Resource.meds = itemIntArray[4];
    Resource.tents = itemIntArray[5];
    Resource.ration = itemIntArray[6];
    Resource.trabbihp = itemIntArray[7];
    Resource.trabbispeed = itemIntArray[8];
}

// Name und Restliche Int-Werte der Playerobjekte werden separat aus der
// Datenbank geholt und gesetzt
public void loadPlayer() {
    String[] namecolumn = { "Name" };
    String[] intcolumn = { "ID, Name, HP, Satisfaction, Hygiene, IsAlive" };
    String[] namesToString = new String[4];

    Cursor playerCursor = db.query("playertable", intcolumn, null, null,
            null, null, "ID");
    playerCursor.moveToPosition(-1);
    int i = 0;
    while (i <= 3) {
        playerCursor.moveToNext();
        String temp = playerCursor.getString(1);
        Resource.playerArray[i].setName(temp);
        int tempint = playerCursor.getInt(2);
        Resource.playerArray[i].setHp(tempint);
        tempint = playerCursor.getInt(3);
        Resource.playerArray[i].setsatisfaction(tempint);
        tempint = playerCursor.getInt(4);
        Resource.playerArray[i].setHygieneInt(tempint);
        tempint = playerCursor.getInt(5);
        Resource.playerArray[i].setAliveInt(tempint);
        i++;

    }
}

public void dropTables() {
    db.execSQL("DROP TABLE 'playertable';");
    db.execSQL("DROP TABLE 'itemtable';");
}

private int[] cursorToInt(Cursor cursor, int n) {
    int[] results = new int[n];
    for (int i = 0; i <= n - 1; i++) {
        results[i] = cursor.getInt(i + 1);
    }

    return results;
}

private String[] cursorToString(Cursor cursor) {
    String[] results = new String[4];
    int columnIndex = cursor.getColumnIndex("Name");
    for (int i = 0; i <= 3; i++) {
        results[i] = cursor.getString(columnIndex);
    }

    return results;
}

}
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    this.myDB = new DB(this);
    initUI();
    testcase1();