Android 在SQLite中重新创建表
在实现数据库的save-/loadfunction时,我删除了这些表,以查看我的应用程序是否可以在必要时处理表的创建—当然,它不能 所以在我的testactivity的onCreate中,我创建了一个DB实例,它在它的构造函数中创建了一个DBOpenHelper实例。 基本上,当DBOpenHelper实例调用getWritableDatabase()时,应该执行DBOpenHelper的onCreate,在我的数据库中创建表。 我认为问题在于,getWritableDatabase()没有被调用,因为数据库本身已经存在——我想我读过类似这样的东西,它吸收了openOrCreateDatabase的功能 如何确保在不存在表的情况下重新创建表,而无需每次删除和重新创建数据库 DBOpenhelper:Android 在SQLite中重新创建表,android,database,sqlite,Android,Database,Sqlite,在实现数据库的save-/loadfunction时,我删除了这些表,以查看我的应用程序是否可以在必要时处理表的创建—当然,它不能 所以在我的testactivity的onCreate中,我创建了一个DB实例,它在它的构造函数中创建了一个DBOpenHelper实例。 基本上,当DBOpenHelper实例调用getWritableDatabase()时,应该执行DBOpenHelper的onCreate,在我的数据库中创建表。 我认为问题在于,getWritableDatabase()没有被调
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();