问题:写入一个数据库中的两个不同的表

时间:2014-02-09 11:26:07

标签: android sqlite android-asynctask

我有两个类“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)

1 个答案:

答案 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计数器来处理数据库连接关闭。