说明
您似乎正在尝试使用多个数据库助手,每个表一个用于同一个数据库。 只有一个 Helper,第一个,在数据库的生命周期中遇到,会调用 onCreate 方法,因此您可能会遇到问题。
典型的解决方法是使用单个数据库助手(它不是表助手)。
假设您有一个用于 Users 表的数据库助手:-
public class DatabaseUserHelper extends SQLiteOpenHelper {
private static final int DATABASE_VERSION = 1;
private static final String DATABASE_NAME = DatabaseContents.DATABASE.toString();
public DatabaseUserHelper(Context context) {
super(context, DATABASE_NAME, null,DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
Log.d("CREATEUSER","Creating User Table");
db.execSQL("CREATE TABLE " + DatabaseContents.TABLE_USERS +
"(" +
"_id INTEGER PRIMARY KEY," +
" username text" +
")");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
并且您拥有问题中包含的 DatabasePesertaHelper,然后使用:-
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DatabaseUserHelper userHelper = new DatabaseUserHelper(this);
logTables(userHelper.getWritableDatabase());
DatabasePesertaHelper pesertaHelper = new DatabasePesertaHelper(this);
logTables(pesertaHelper.getWritableDatabase());
}
private void logTables(SQLiteDatabase db) {
Cursor c = db.query("sqlite_master",null,null,null,null,null,null);
DatabaseUtils.dumpCursor(c);
c.close();
}
}
并且应用程序从新运行,然后日志包含:-
12-29 09:34:28.582 2511-2511/? D/CREATEUSER: Creating User Table
12-29 09:34:28.587 2511-2511/? I/System.out: >>>>> Dumping cursor android.database.sqlite.SQLiteCursor@1351978
12-29 09:34:28.587 2511-2511/? I/System.out: 0 {
12-29 09:34:28.587 2511-2511/? I/System.out: type=table
12-29 09:34:28.587 2511-2511/? I/System.out: name=android_metadata
12-29 09:34:28.587 2511-2511/? I/System.out: tbl_name=android_metadata
12-29 09:34:28.587 2511-2511/? I/System.out: rootpage=3
12-29 09:34:28.587 2511-2511/? I/System.out: sql=CREATE TABLE android_metadata (locale TEXT)
12-29 09:34:28.587 2511-2511/? I/System.out: }
12-29 09:34:28.587 2511-2511/? I/System.out: 1 {
12-29 09:34:28.587 2511-2511/? I/System.out: type=table
12-29 09:34:28.588 2511-2511/? I/System.out: name=users
12-29 09:34:28.588 2511-2511/? I/System.out: tbl_name=users
12-29 09:34:28.588 2511-2511/? I/System.out: rootpage=4
12-29 09:34:28.588 2511-2511/? I/System.out: sql=CREATE TABLE users(_id INTEGER PRIMARY KEY, username text)
12-29 09:34:28.588 2511-2511/? I/System.out: }
12-29 09:34:28.588 2511-2511/? I/System.out: <<<<<
12-29 09:34:28.590 2511-2511/? I/System.out: >>>>> Dumping cursor android.database.sqlite.SQLiteCursor@fdb49b7
12-29 09:34:28.590 2511-2511/? I/System.out: 0 {
12-29 09:34:28.590 2511-2511/? I/System.out: type=table
12-29 09:34:28.590 2511-2511/? I/System.out: name=android_metadata
12-29 09:34:28.590 2511-2511/? I/System.out: tbl_name=android_metadata
12-29 09:34:28.590 2511-2511/? I/System.out: rootpage=3
12-29 09:34:28.590 2511-2511/? I/System.out: sql=CREATE TABLE android_metadata (locale TEXT)
12-29 09:34:28.590 2511-2511/? I/System.out: }
12-29 09:34:28.590 2511-2511/? I/System.out: 1 {
12-29 09:34:28.590 2511-2511/? I/System.out: type=table
12-29 09:34:28.590 2511-2511/? I/System.out: name=users
12-29 09:34:28.590 2511-2511/? I/System.out: tbl_name=users
12-29 09:34:28.590 2511-2511/? I/System.out: rootpage=4
12-29 09:34:28.590 2511-2511/? I/System.out: sql=CREATE TABLE users(_id INTEGER PRIMARY KEY, username text)
12-29 09:34:28.590 2511-2511/? I/System.out: }
12-29 09:34:28.590 2511-2511/? I/System.out: <<<<<
即User 表已创建,虽然 DatabasePesertaHelper 没有问题,但未创建 Peserta 表(如果交换了实例化 usersHelper 和 pesertaHelper 的顺序并且 pesertaHelper 是第一个,则只有 Peserta 表将是仅当数据库不存在时才创建)。
建议修复
典型的解决方法是将两个表合并到一个助手中,然后卸载应用程序并重新运行。
- 请注意,这将删除所有现有数据,这在开发应用程序时通常是可以接受的。
因此,如上所示的 DatabaseUserHelper 可能会变成:-
public class DatabaseUserHelper extends SQLiteOpenHelper {
private static final int DATABASE_VERSION = 1;
private static final String DATABASE_NAME = DatabaseContents.DATABASE.toString();
public DatabaseUserHelper(Context context) {
super(context, DATABASE_NAME, null,DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
Log.d("CREATEUSER","Creating User Table");
db.execSQL("CREATE TABLE " + DatabaseContents.TABLE_USERS +
"(" +
"_id INTEGER PRIMARY KEY," +
" username text" +
")");
Log.d("CREATEPESERTA","Creating Perserta Table");
db.execSQL("CREATE TABLE peserta" + "("
+ "_id INTEGER PRIMARY KEY,"
+ "nama TEXT(100),"
+ "jenis_kelamin TEXT(1),"
+ "tempat_lahir TEXT(20),"
+ "tgl_lahir TEXT(12),"
+ "alamat TEXT(30),"
+ "agama TEXT(30),"
+ "id_ortu INTEGER,"
+ "FOREIGN KEY (id_ortu) REFERENCES " + DatabaseContents.TABLE_USERS + "(_id)"
+ ");");
Log.d("CREATE DATABASE", "Create " + DatabaseContents.TABLE_PESERTA + " Successfully.");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
删除应用程序的数据(或卸载应用程序)并重新运行上述活动代码后:-
12-29 10:01:37.265 D/CREATEUSER: Creating User Table
12-29 10:01:37.265 D/CREATEPESERTA: Creating Perserta Table
12-29 10:01:37.265 D/CREATE DATABASE: Create peserta Successfully.
12-29 10:01:37.270 I/System.out: >>>>> Dumping cursor android.database.sqlite.SQLiteCursor@1351978
12-29 10:01:37.270 I/System.out: 0 {
12-29 10:01:37.270 I/System.out: type=table
12-29 10:01:37.270 I/System.out: name=android_metadata
12-29 10:01:37.270 I/System.out: tbl_name=android_metadata
12-29 10:01:37.270 I/System.out: rootpage=3
12-29 10:01:37.270 I/System.out: sql=CREATE TABLE android_metadata (locale TEXT)
12-29 10:01:37.270 I/System.out: }
12-29 10:01:37.270 I/System.out: 1 {
12-29 10:01:37.270 I/System.out: type=table
12-29 10:01:37.270 I/System.out: name=users
12-29 10:01:37.270 I/System.out: tbl_name=users
12-29 10:01:37.270 I/System.out: rootpage=4
12-29 10:01:37.270 I/System.out: sql=CREATE TABLE users(_id INTEGER PRIMARY KEY, username text)
12-29 10:01:37.270 I/System.out: }
12-29 10:01:37.270 I/System.out: 2 {
12-29 10:01:37.270 I/System.out: type=table
12-29 10:01:37.270 I/System.out: name=peserta
12-29 10:01:37.270 I/System.out: tbl_name=peserta
12-29 10:01:37.270 I/System.out: rootpage=5
12-29 10:01:37.270 I/System.out: sql=CREATE TABLE peserta(_id INTEGER PRIMARY KEY,nama TEXT(100),jenis_kelamin TEXT(1),tempat_lahir TEXT(20),tgl_lahir TEXT(12),alamat TEXT(30),agama TEXT(30),id_ortu INTEGER,FOREIGN KEY (id_ortu) REFERENCES users(_id))
12-29 10:01:37.270 I/System.out: }
12-29 10:01:37.270 I/System.out: <<<<<
12-29 10:01:37.273 I/System.out: >>>>> Dumping cursor android.database.sqlite.SQLiteCursor@fdb49b7
12-29 10:01:37.273 I/System.out: 0 {
12-29 10:01:37.273 I/System.out: type=table
12-29 10:01:37.273 I/System.out: name=android_metadata
12-29 10:01:37.273 I/System.out: tbl_name=android_metadata
12-29 10:01:37.273 I/System.out: rootpage=3
12-29 10:01:37.273 I/System.out: sql=CREATE TABLE android_metadata (locale TEXT)
12-29 10:01:37.273 I/System.out: }
12-29 10:01:37.273 I/System.out: 1 {
12-29 10:01:37.273 I/System.out: type=table
12-29 10:01:37.273 I/System.out: name=users
12-29 10:01:37.273 I/System.out: tbl_name=users
12-29 10:01:37.273 I/System.out: rootpage=4
12-29 10:01:37.273 I/System.out: sql=CREATE TABLE users(_id INTEGER PRIMARY KEY, username text)
12-29 10:01:37.273 I/System.out: }
12-29 10:01:37.273 I/System.out: 2 {
12-29 10:01:37.274 I/System.out: type=table
12-29 10:01:37.274 I/System.out: name=peserta
12-29 10:01:37.274 I/System.out: tbl_name=peserta
12-29 10:01:37.274 I/System.out: rootpage=5
12-29 10:01:37.274 I/System.out: sql=CREATE TABLE peserta(_id INTEGER PRIMARY KEY,nama TEXT(100),jenis_kelamin TEXT(1),tempat_lahir TEXT(20),tgl_lahir TEXT(12),alamat TEXT(30),agama TEXT(30),id_ortu INTEGER,FOREIGN KEY (id_ortu) REFERENCES users(_id))
12-29 10:01:37.274 I/System.out: }
12-29 10:01:37.274 I/System.out: <<<<<
- 请注意,不需要 DatabasePesertahelper,因为 DatabaseUserHelper 提供对这两个表的访问。