我有两个类“StaffListDB”和“CostCentreListDB”,它们是两个表结构。我已经为两个类提到了DataBase名称为“B”。当我尝试从ASYNC任务写入这些表时,它给了我一个错误。我尝试从两个单独的ASYNC任务写入这些表仍然是同一个问题。 但是,当我将其中一个DataBase名称更改为除“B”以外的任何内容以表示“DB”时,它可以正常工作。任何帮助建议非常感谢。谢谢。
My database classes:
public class StaffListDB {
private static final String KEY_STAFFID = "StaffId";
private static final String KEY_STAFFNAME = "StaffName";
private static final String DATABASE_NAME = "B";
private static final String DATABASE_TABLE = "StaffList";
private static final int DATABASE_VERSION = 1;
private DBStaffListHelper staffListHelper;
private final Context staffListContext;
private SQLiteDatabase staffListDatabase;
private static class DBStaffListHelper extends SQLiteOpenHelper {
public DBStaffListHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE " + DATABASE_TABLE + " (" + KEY_STAFFID
+ " TEXT NOT NULL, " + KEY_STAFFNAME + " TEXT NOT NULL);"
);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + DATABASE_TABLE);
onCreate(db);
}
}
public StaffListDB (Context c){
staffListContext = c;
}
public StaffListDB open() throws SQLException{
staffListHelper = new DBStaffListHelper(staffListContext);
staffListDatabase = staffListHelper.getWritableDatabase();
return this;
}
public void close(){
staffListHelper.close();
}
public long createStaffEntry(String staffIdd, String name) {
ContentValues cv = new ContentValues();
cv.put(KEY_STAFFID, staffIdd);
cv.put(KEY_STAFFNAME, name);
return staffListDatabase.insert(DATABASE_TABLE, null, cv);
}
public String getStaffData() {
String[] columns = new String[]{KEY_STAFFID, KEY_STAFFNAME};
Cursor c = staffListDatabase.query(DATABASE_TABLE, columns, null, null, null, null, null);
String result = "";
int iStaffId = c.getColumnIndex(KEY_STAFFID);
int iStaffName = c.getColumnIndex(KEY_STAFFNAME);
for(c.moveToFirst(); !c.isAfterLast();c.moveToNext()){
result = result + c.getString(iStaffId) + " " + c.getString(iStaffName) + "\n";
}
return result;
}
public void deleteTable() throws SQLException{
staffListDatabase.execSQL("DELETE FROM " + DATABASE_TABLE);
}
}
public class CostCentreListDB {
private static final String KEY_COSTCODE = "CostCode";
private static final String KEY_COSTCODENAME = "CCName";
private static final String DATABASE_NAME= "B";
private static final String DATABASE_TABLE = "CostCentreListTable";
private static final int DATABASE_VERSION = 1;
private DBCCListHelper ccListHelper;
private final Context ccListContext;
private SQLiteDatabase ccListDatabase;
private static class DBCCListHelper extends SQLiteOpenHelper{
public DBCCListHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE "+ DATABASE_TABLE + " (" +
KEY_COSTCODE + " TEXT NOT NULL, " +
KEY_COSTCODENAME + " TEXT NOT NULL);"
);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + DATABASE_TABLE);
onCreate(db);
}
}
public CostCentreListDB (Context c){
ccListContext = c;
}
public CostCentreListDB open() throws SQLException{
ccListHelper = new DBCCListHelper(ccListContext);
ccListDatabase = ccListHelper.getWritableDatabase();
return this;
}
public void close(){
ccListHelper.close();
}
public long createCCEntry(String costCode, String costCodeName) {
ContentValues cv = new ContentValues();
cv.put(KEY_COSTCODE, costCode);
cv.put(KEY_COSTCODENAME, costCodeName);
return ccListDatabase.insert(DATABASE_TABLE, null, cv);
}
public String getCCData() {
String[] columns = new String[]{KEY_COSTCODE, KEY_COSTCODENAME};
Cursor c = ccListDatabase.query(DATABASE_TABLE, columns, null, null, null, null, null);
String result = "";
int iCostCode = c.getColumnIndex(KEY_COSTCODE);
int iCostCodeName = c.getColumnIndex(KEY_COSTCODENAME);
for(c.moveToFirst(); !c.isAfterLast();c.moveToNext()){
result = result + c.getString(iCostCode) + " " + c.getString(iCostCodeName) + "\n";
}
return result;
}
}
异步任务: 公共类SaveServerInfoInDataBase扩展了AsyncTask {
@Override
protected Void doInBackground(String... params) {
String staffId = params[0];
String staffName = params[1];
for(int i = 0; i<=10; i++){
StaffListDB saveStaffList = new StaffListDB(MainActivity.this);
saveStaffList.open();
//saveStaffList.deleteTable();
saveStaffList.createStaffEntry(staffId + i, staffName + i);
saveStaffList.close();
CostCentreListDB saveCC = new CostCentreListDB(MainActivity.this);
saveCC.open();
saveCC.createCCEntry("200" + i, "IT" + i);
saveCC.close();
}
return null;
}
}
logcat的:
02-09 11:20:42.778: E/SQLiteLog(7104): (1) no such table: CostCentreListTable
02-09 11:20:43.068: E/SQLiteDatabase(7104): Error inserting CostCode=2000 CCName=IT0
02-09 11:20:43.068: E/SQLiteDatabase(7104): android.database.sqlite.SQLiteException: no such table: CostCentreListTable (code 1): , while compiling: INSERT INTO CostCentreListTable(CostCode,CCName) VALUES (?,?)
02-09 11:20:43.068: E/SQLiteDatabase(7104): at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
02-09 11:20:43.068: E/SQLiteDatabase(7104): at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:1108)
02-09 11:20:43.068: E/SQLiteDatabase(7104): at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:681)
02-09 11:20:43.068: E/SQLiteDatabase(7104): at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:589)
02-09 11:20:43.068: E/SQLiteDatabase(7104): at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:58)
02-09 11:20:43.068: E/SQLiteDatabase(7104): at android.database.sqlite.SQLiteStatement.<init>(SQLiteStatement.java:31)
02-09 11:20:43.068: E/SQLiteDatabase(7104): at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1573)
02-09 11:20:43.068: E/SQLiteDatabase(7104): at android.database.sqlite.SQLiteDatabase.insert(SQLiteDatabase.java:1445)
02-09 11:20:43.068: E/SQLiteDatabase(7104): at com.example.testsqlite.CostCentreListDB.createCCEntry(CostCentreListDB.java:69)
02-09 11:20:43.068: E/SQLiteDatabase(7104): at com.example.testsqlite.MainActivity$SaveServerInfoInDataBase.doInBackground(MainActivity.java:90)
02-09 11:20:43.068: E/SQLiteDatabase(7104): at com.example.testsqlite.MainActivity$SaveServerInfoInDataBase.doInBackground(MainActivity.java:1)
02-09 11:20:43.068: E/SQLiteDatabase(7104): at android.os.AsyncTask$2.call(AsyncTask.java:287)
02-09 11:20:43.068: E/SQLiteDatabase(7104): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
02-09 11:20:43.068: E/SQLiteDatabase(7104): at java.util.concurrent.FutureTask.run(FutureTask.java:137)
02-09 11:20:43.068: E/SQLiteDatabase(7104): at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
02-09 11:20:43.068: E/SQLiteDatabase(7104): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
02-09 11:20:43.068: E/SQLiteDatabase(7104): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
02-09 11:20:43.068: E/SQLiteDatabase(7104): at java.lang.Thread.run(Thread.java:856)
答案 0 :(得分:0)
使用两个不同的数据库连接写入同一个数据库文件是不正确的。当您尝试使用不同的连接同时写入文件时,您将遇到数据库锁定异常。
您必须确保使用一个数据库连接。您可以实现扩展SQLiteOpenHelper的单例数据库帮助程序。
public class DataBaseHelper extends SQLiteOpenHelper {
public static final int DATABASE_VERSION = 1;
public static final String DATABASE_NAME = "db_name";
private static DataBaseHelper mInstance = null;
private DataBaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
public static DataBaseHelper getInstance(Context context) {
if (mInstance == null)
mInstance = new DataBaseHelper(context.getApplicationContext());
return mInstance;
}
@Override
public void onCreate(SQLiteDatabase db) {/* ... */}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {/* ... */}
}
然后在任何地方使用扩展类
public class StaffListDAO {
private DataBaseHelper mDbHelper;
public static String TableName = "StaffList";
private static final String KEY_STAFFID = "StaffId";
private static final String KEY_STAFFNAME = "StaffName";
private StaffListDAO(Context context) {
mDbHelper = DataBaseHelper.getInstance(context);
}
public static StaffListDAO getInstance(Context context) {
return new StaffListDAO(context);
}
public void insert(Staff item) {
SQLiteDatabase db = mDbHelper.getWritableDatabase();
ContentValues values = new ContentValues();
// fill values
db.insert(TableName, null, values);
}
}
请注意,我通常不会关闭数据库连接,因为它会在应用完成后自动释放。您可以实现一个ref计数器来处理数据库连接关闭。