2014-02-09 2 views
0

У меня есть два класса «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

Зачем создавать 2 вложенных класса, которые расширяют SQLiteOpenHelper? Создайте только 1 класс и обработайте все свои db. –

+1

@udi. да, сделайте это сейчас, и теперь он отлично работает. Спасибо – BRDroid

ответ

0

Использование двух различных соединений с базой данных для записи в тот же файл базы данных не является правильным. Вы будете сталкиваться с исключением блокировки базы данных при попытке записи в файл одновременно с использованием разных подключений.

Вы должны убедиться, что используете одно соединение db. вы можете реализовать помощник базы данных singleton, который расширяет 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 для соединения соединения db.

+0

Благодарим вас за ценные предложения. Да, я сделал необходимые изменения, и теперь он работает отлично. – BRDroid

Смежные вопросы