2012-03-27 120 views
2

只是将我的硬编码数据更改为使用SQLite数据库浏览器的数据库。在我更改所有查询之前,我的工作正常,但在更改时发生错误。我不能再做这些查询了。数据库只能读取但不能写入。当客户将食物订购到“Bill”表中时,我试图插入条目但失败。我的数据库文件在资产/ Restaurantdb.sqlSQLiteReadOnlyDatabaseException:尝试写入只读数据库

一个更奇怪的发现是,我卸载了整个事情,在我的“食物”表改变一些食品的名称(如汉堡到Burger1),它表明汉堡,而不是Burger1。

++++++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++++++++++++++++++++++ 这是我的最新代码,但它最终得到了这个新的错误。我的数据库文件名为“Restaurantdb”的资产文件夹。 错误:没有这样的食物检索食物名称时 ++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++++++++++ +++++

package com.restaurant.sesame; 


    import java.io.FileOutputStream; 
    import java.io.IOException; 
    import java.io.InputStream; 
    import java.io.OutputStream; 
    import android.content.ContentValues; 
    import android.content.Context; 
    import android.database.Cursor; 
    import android.database.SQLException; 
    import android.database.sqlite.SQLiteDatabase; 
    import android.database.sqlite.SQLiteException; 
    import android.database.sqlite.SQLiteOpenHelper; 
    import android.util.Log; 
    import android.widget.Toast; 

public class Restaurant { 
    public static final String KEY_ROWID = "_id"; 
    public static final String KEY_NAME = "name"; 
    public static final String KEY_DETAIL = "detail"; 
    public static final String KEY_PRICE = "price"; 


private static String DATABASE_NAME ="Restaurantdb"; 
private static String DATABASE_TABLE ="Food"; 
private static final int DATABASE_VERSION = 1; 
private static String DB_PATH = "/data/data/com.restaurant.sesame/databases/"; 

private static SQLiteDatabase ourDatabase; 
private static Context myContext; 
private DBHelper ourHelper; 

private static class DBHelper extends SQLiteOpenHelper{ 

    public DBHelper(Context context) { 
     super(context, DATABASE_NAME, null, DATABASE_VERSION); 


    } 

    public void createDataBase() throws IOException{ 

     boolean dbExist = checkDataBase(); 

     if(dbExist){ 
      //do nothing - database already exist 
     }else{ 

      //By calling this method and empty database will be created into the default system path 
       //of your application so we are gonna be able to overwrite that database with our database. 
      this.getReadableDatabase(); 

      try { 

       copyDataBase(); 

      } catch (IOException e) { 

       throw new Error("Error copying database"); 

      } 
     } 

    } 

    /** 
    * Check if the database already exist to avoid re-copying the file each time you open the application. 
    * @return true if it exists, false if it doesn't 
    */ 
    private boolean checkDataBase(){ 

     SQLiteDatabase checkDB = null; 

     try{ 
      String myPath = DB_PATH + DATABASE_NAME; 
      checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY); 

     }catch(SQLiteException e){ 

      /* database does't exist yet. */ 

     } 

     if(checkDB != null){ 

      checkDB.close(); 

     } 

     return checkDB != null ? true : false; 
    } 

    /** 
    * Copies your database from your local assets-folder to the just created empty database in the 
    * system folder, from where it can be accessed and handled. 
    * This is done by transfering bytestream. 
    * */ 
    private void copyDataBase() throws IOException{ 

     //Open your local db as the input stream 
     InputStream myInput = myContext.getAssets().open(DATABASE_NAME); 

     // Path to the just created empty db 
     String outFileName = DB_PATH + DATABASE_NAME; 

     //Open the empty db as the output stream 
     OutputStream myOutput = new FileOutputStream(outFileName); 

     //transfer bytes from the inputfile to the outputfile 
     byte[] buffer = new byte[1024]; 
     int length; 
     while ((length = myInput.read(buffer))>0){ 
      myOutput.write(buffer, 0, length); 
     } 

     //Close the streams 
     myOutput.flush(); 
     myOutput.close(); 
     myInput.close(); 

    } 

    public void openDataBase() throws SQLException{ 

     //Open the database 
     String myPath = DB_PATH + DATABASE_NAME; 
     ourDatabase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY); 

    } 

    @Override 
    public synchronized void close() { 

      if(ourDatabase != null) 
       ourDatabase.close(); 

      super.close(); 

    } 
    @Override 
    public void onCreate(SQLiteDatabase db) { 

    } 

    @Override 
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 

    } 



} 

public Restaurant(Context c) 
{ 
    myContext = c; 

    DBHelper helper = new DBHelper (myContext); 
    this.ourDatabase = helper.getWritableDatabase(); 
} 

public Restaurant open() throws SQLException 
{ 
    ourHelper = new DBHelper (myContext); 

    try { 

     ourHelper.createDataBase(); 

    } catch (IOException ioe) { 

     throw new Error("Unable to create database"); 

    } 

    try { 

     ourHelper.openDataBase(); 

    }catch(SQLException sqle){ 

     throw sqle; 

    } 
    return this; 
} 

public void close() 
{ 
    ourHelper.close(); 
} 



public String[] getWantedInfos(String KEY_WANTED){ 
    String[]columns = new String[]{KEY_WANTED}; 
    Cursor c = ourDatabase.query(DATABASE_TABLE, columns, null, null, null, null, null); 
    String [] wanted = new String[c.getCount()] ; 
    int i = 0, 
     iWanted = c.getColumnIndex(KEY_WANTED); 

    for(c.moveToFirst();!c.isAfterLast();c.moveToNext()) 
     { 
      wanted[i] = c.getString(iWanted); 
      ++i; 
     } 
    return wanted; 
} 

public String getOneInfo(String id, String info) 
{ 
    Log.w("my app", "IN getOneInfo TOP!!!!"); 
    String [] columns = new String [] {id,info};  

    Cursor c = ourDatabase.query(DATABASE_TABLE, columns, KEY_ROWID + " = "+ id, null, null, null, null); 
    Log.w("getOneInfo", "IN getOneInfo after query!!!!"); 
    String result =""; 
    int iRow = c.getColumnIndex(id); 
    int iInfo = c.getColumnIndex(info); 

    if(c!=null){ 
     c.moveToFirst(); 
     result =c.getString(iInfo); 
     return result; 
    } 
    return null; 

} 

public String getBillInfo(String name, String info) 
{ 
    Log.w("getBillInfo", "IN getBillInfo TOP!!!!"); 
    String [] columns = new String [] {KEY_NAME,info}; 
    Log.w("getBillInfo ","pass in"+ name); 
    Log.w("getBillInfo", "pass in"+info); 
    Cursor c = ourDatabase.query("Bill", columns, "name = '"+ name+ "'", null, null, null, null); 
    Log.w("getBillInfo", "IN getBillInfo after query!!!!"); 
    String result =""; 

    int iInfo = c.getColumnIndex(info); 
    Log.w("getBillInfo", "IN getBillInfo before loop!!!!"); 

    for(c.moveToFirst();!c.isAfterLast();c.moveToNext()) 
    { 
     Log.w("getBillInfo", "IN getBillInfo inside loop!!!!"); 
     c.moveToFirst(); 
     result =c.getString(iInfo); 
     Log.w("getBillInfo", "IN getBillInfo XXXXnull!!!!"); 
     Log.w("getBillInfo", "quantity in bill is ==>"+result); 
     return result; 
    } 
    Log.w("getBillInfo", "IN getBillInfo null!!!!"); 
    return "0"; 

} 
public String getBillTotal() 
{ 
    Log.w("Bill Total", "YYYY33333"); 
    Cursor c = ourDatabase.rawQuery(
      "SELECT SUM(total)as total FROM Bill", null); 
    Log.w("Bill Total", "YYYY4444"); 
    String result =""; 
    int iInfo = c.getColumnIndex("total"); 
    Log.w("Bill Total", "YYYY5555"); 
    if(c!=null){ 
     c.moveToFirst(); 
     result =c.getString(iInfo); 
     return result; 
    } 
    return "0.00"; 

} 

public String getBillData() 
{ 
    Log.w("my app", "IN getData TOP!!!!"); 
    String [] columns = new String [] {"_id","name","price","quantity","total"};  

    Cursor c = ourDatabase.query("Bill", columns, null, null, "name", null, null); 
    String result =""; 
    int iRow = c.getColumnIndex("_id"); 
    int iName = c.getColumnIndex("name"); 
    int iPrice = c.getColumnIndex("price"); 
    int iQuantity = c.getColumnIndex("quantity"); 
    int iTotal = c.getColumnIndex("total"); 
    Log.w("my app", "IN getData MIDDLE!!!!"); 
    int i = 1; 
    for(c.moveToFirst();!c.isAfterLast();c.moveToNext()) 
    { 
     result = result + Integer.toString(i)+"\t" + 
          c.getString(iName) + "\t" + 
          c.getString(iPrice) +"\t" + 
          c.getString(iQuantity) + "\t" + 
          c.getString(iTotal) + "\n"; 
     i++; 
    } 
    Log.w("my app", "IN getData END!!!!"); 
    return result; 

} 
public long createOrderEntry(int id, int quantityItem) 
{ 
    String [] columns = new String [] {KEY_ROWID,KEY_NAME,KEY_PRICE}; 
    Cursor c = ourDatabase.query(DATABASE_TABLE, columns, KEY_ROWID + "=" + Integer.toString(id) , null, null, null, null); 

    if(c!= null) 
    { 
     ContentValues cv = new ContentValues(); 
     c.moveToFirst(); 
     String nameItem = c.getString(1); 
     double priceItem = c.getDouble(2); 
     double totalItem = priceItem *quantityItem; 
     cv.put("name", nameItem); 
     cv.put("price", priceItem); 
     cv.put("quantity", quantityItem); 
     cv.put("total", totalItem); 

     return ourDatabase.insert("Bill", null, cv); 

    } 
    return 0; 
} 

public boolean deleteOrderEntry(int lRow) 
{ 
    String [] columns = new String [] {KEY_ROWID,KEY_NAME,KEY_PRICE}; 
    Log.w("my app", "deleteOrderEntry Top"); 
    Cursor c = ourDatabase.query(DATABASE_TABLE, columns, KEY_ROWID + "= " + Integer.toString(lRow) , null, null, null, null); 
    Log.w("my app", "deleteOrderEntry 2"); 
    if(c!= null) 
    { 
     c.moveToFirst(); 
     String nameItem = c.getString(1); 
     ourDatabase.delete("Bill", "name = '"+ nameItem+ "'", null); 
     Log.w("my app", "deleteOrderEntry MIDDLE"); 
     return true; 
    } 
    return false; 

} 
public void truncateBill(){ 
    ourDatabase.execSQL("DELETE FROM Bill"); 
    ourDatabase.execSQL("VACUUM"); 
} 

}

+1

请忽略棕色(评论颜色)。我的代码没有被评论。我不是为什么它显示这样的。 (我尝试在stackaflow中多次更改) – 2012-03-27 07:23:19

+0

只是删除评论表单数据库尚不存在,或'从它... – pojomx 2015-08-19 01:00:27

+0

使用getWritableDatabase(),而不是getReadableDatabase() – 2016-11-18 10:06:28

回答

4

You need to make a writable database if you want to insert values in database need to在构造函数中添加这些行

DBHelper helper = new DBHelper (mCtx); 
       this.db = helper.getWritableDatabase(); 

     public Restaurant(Context c) 
{ 
    myContext = c; 

       DBHelper helper = new DBHelper (mCtx); 
      this.db = helper.getWritableDatabase(); 
}   
+0

什么是mCtx?它说不能解决为可变。 – 2012-03-27 12:35:45

+0

它是一个Context对象,比如private static Context myContext; – 2012-03-27 12:38:46

4

无法写入到存储在您的资产文件夹,因为这是你的apk的部分数据库并且不能改变。

当您的应用程序运行时,应检查数据库的存在情况(在普通数据库文件夹中),如果不存在,请从资产文件夹复制数据库并使用该数据库。

查看这些链接了解更多信息。

http://www.devx.com/wireless/Article/40842

Ship an application with a database

0
public void openDataBase() throws SQLException{ 

    //Open the database 
    String myPath = DB_PATH + DATABASE_NAME; 
    ourDatabase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY); 

} 

您必须更改SQLiteDatabase.OPEN_READONLYSQLiteDatabase.OPEN_READWRITE,因为OPEN_READONLY只允许读不能写。