【问题标题】:SQLiteException: No such table even if there is tableSQLiteException:即使有表也没有这样的表
【发布时间】:2014-07-15 07:03:34
【问题描述】:

在尝试从 SQLite db 获取值时出现此错误:-

07-15 02:49:33.040: E/SQLiteLog(1770): (1) no such table: collegelist
07-15 02:49:33.040: D/AndroidRuntime(1770): Shutting down VM
07-15 02:49:33.050: W/dalvikvm(1770): threadid=1: thread exiting with uncaught exception (group=0xb2acaba8)
07-15 02:49:33.050: E/AndroidRuntime(1770): FATAL EXCEPTION: main
07-15 02:49:33.050: E/AndroidRuntime(1770): Process: com.existingsqlitedatabase, PID: 1770
07-15 02:49:33.050: E/AndroidRuntime(1770): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.existingsqlitedatabase/com.existingsqlitedatabase.MainActivity}: android.database.sqlite.SQLiteException: no such table: collegelist (code 1): , while compiling: SELECT * FROM collegelist
07-15 02:49:33.050: E/AndroidRuntime(1770):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2195)
07-15 02:49:33.050: E/AndroidRuntime(1770):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245)
07-15 02:49:33.050: E/AndroidRuntime(1770):     at android.app.ActivityThread.access$800(ActivityThread.java:135)
07-15 02:49:33.050: E/AndroidRuntime(1770):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
07-15 02:49:33.050: E/AndroidRuntime(1770):     at android.os.Handler.dispatchMessage(Handler.java:102)

我已经检查了我的数据库(colleges) 中的表(collegelist),它就在那里,但我不知道为什么它没有读取它。我还在这里查看了一些与它相关的早期帖子,但它们没有帮助。

这是我的 DatabaseHelper 类:-

public class DataBaseHelper extends SQLiteOpenHelper 
{ 
private static String TAG = "DataBaseHelper"; // Tag just for the LogCat window 
//destination path (location) of our database on device 
private static String DB_PATH = "";  
private static String DB_NAME ="colleges";// Database name 
private SQLiteDatabase mDataBase;  
private final Context mContext; 

public DataBaseHelper(Context context)  
{ 
super(context, DB_NAME, null, 1);// 1? its Database Version 
DB_PATH = context.getApplicationInfo().dataDir + "/databases/"; 
this.mContext = context; 
}    

public void createDataBase() throws IOException 
{ 
//If database not exists copy it from the assets 

boolean mDataBaseExist = checkDataBase(); 
if(!mDataBaseExist) 
{ 
    this.getReadableDatabase(); 
    this.close(); 
    try  
    { 
        //Copy the database from assests 
        copyDataBase(); 
        Log.e(TAG, "createDatabase database created"); 
    }  
    catch (IOException mIOException)  
    { 
        throw new Error("ErrorCopyingDataBase"); 
    } 
  } 
} 
//Check that the database exists here: /data/data/your package/databases/Da Name 
private boolean checkDataBase() 
{ 
    File dbFile = new File(DB_PATH + DB_NAME); 
    //Log.v("dbFile", dbFile + "   "+ dbFile.exists()); 
    return dbFile.exists(); 
} 

//Copy the database from assets 
private void copyDataBase() throws IOException 
{ 
    InputStream mInput = mContext.getAssets().open(DB_NAME); 
    String outFileName = DB_PATH + DB_NAME; 
    OutputStream mOutput = new FileOutputStream(outFileName); 
    byte[] mBuffer = new byte[1024]; 
    int mLength; 
    while ((mLength = mInput.read(mBuffer))>0) 
    { 
        mOutput.write(mBuffer, 0, mLength); 
    } 
    mOutput.flush(); 
    mOutput.close(); 
    mInput.close(); 
} 

//Open the database, so we can query it 
public boolean openDataBase() throws SQLException 
{ 
    String mPath = DB_PATH + DB_NAME; 
    //Log.v("mPath", mPath); 
    mDataBase = SQLiteDatabase.openDatabase(mPath, null, SQLiteDatabase.CREATE_IF_NECESSARY); 
    //mDataBase = SQLiteDatabase.openDatabase(mPath, null, SQLiteDatabase.NO_LOCALIZED_COLLATORS); 
    return mDataBase != null; 
} 

@Override 
public synchronized void close()  
{ 
    if(mDataBase != null) 
        mDataBase.close(); 
    super.close(); 
}

@Override
public void onCreate(SQLiteDatabase arg0) {
    // TODO Auto-generated method stub

}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    // TODO Auto-generated method stub

} 

 /**
 * Getting all labels
 * returns list of labels
 * */
public List<String> getAllLabels(){
    List<String> labels = new ArrayList<String>();

    // Select All Query
    String selectQuery = "SELECT * FROM collegelist";

    SQLiteDatabase db = this.getReadableDatabase();
    Cursor cursor = db.rawQuery(selectQuery, null);

    // looping through all rows and adding to list
    if (cursor.moveToFirst()) {
        do {
            labels.add(cursor.getString(1));
        } while (cursor.moveToNext());
    }

    // closing connection
    cursor.close();
    db.close();

    // returning lables
    return labels;
   }
} 

请帮忙。

【问题讨论】:

  • 啊……尽管帮助你们简单地否决了这个问题……看起来否决票给了你某种成就……至少发表适当的评论……
  • 您检查过数据库文件是否真的在 /databases 文件夹中?根据您的代码,如果无法打开数据库文件,则会创建数据库文件,从而导致空数据库(无表)。
  • 出于测试目的,将文件直接推送到那里可能是个好主意。如果查询有效,那么真正的问题是从 /assets 文件夹复制数据库。
  • 是的,仅从资产文件夹复制数据库时出现错误...
  • 没问题,先生。我会找到其他方法的。谢谢你的时间:)

标签: java android database sqlite assets


【解决方案1】:

从资产文件夹加载数据库

public class DataHelper extends SQLiteOpenHelper {

public SQLiteDatabase database = null;
public File databaseFile;
public static String databaseName = "myDb";
public String databasePath = "";
Context mContext;

public DataHelper(Context paramContext) {

    super(paramContext, databaseName, null, 1);
    this.mContext = paramContext;


    this.databasePath = ("data/data/" + paramContext.getPackageName()+"/databases/"+databaseName);
    //this.databasePath = ("data/data/" + paramContext.getPackageName() + "/data.sqlite");
    this.databaseFile = new File(this.databasePath);
    if (!this.databaseFile.exists())
        try {
            deployDataBase(DataHelper.databaseName, this.databasePath);
            return;
        } catch (IOException localIOException) {
            localIOException.printStackTrace();
        }
}

private void deployDataBase(String dbNAme, String dbPath)
        throws IOException {
    InputStream localInputStream = this.mContext.getAssets().open(dbNAme);
    FileOutputStream localFileOutputStream = new FileOutputStream(dbPath);
    byte[] arrayOfByte = new byte[1024];
    while (true) {
        int i = localInputStream.read(arrayOfByte);
        if (i <= 0) {
            localFileOutputStream.flush();
            localFileOutputStream.close();
            localInputStream.close();
            return;
        }
        localFileOutputStream.write(arrayOfByte, 0, i);
    }
}

@Override
public synchronized void close() {

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

    super.close();

}
@Override
public void onCreate(SQLiteDatabase db) {
    // TODO Auto-generated method stub

}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    // TODO Auto-generated method stub

}

}

【讨论】:

  • 使用您的课程后,还在数据库文件夹中创建了一个空数据库,但在数据库文件夹之外又创建了一个文件data.sqlite,其中包含所有内容
  • 我认为这条线是它的原因this.databasePath = ("data/data/" + paramContext.getPackageName() + "/data.sqlite");
  • 是的,这一行是原因,但是这个 data.sqlite 是你的数据库文件,你可以在这个数据库文件上执行你的操作。
  • 我用 `this.databasePath = ("data/data/" + paramContext.getPackageName() + "/databases/"+databaseName);` 更改该行,现在它工作得很好但是当我更改了我数据库中的一些数据并再次测试了代码,更改没有反映出来,你能告诉我为什么吗?我的意思是程序检查了数据库文件是否存在,但是当它发现它存在时,它没有检查数据中的任何更新。
  • 是的,如果发现它没有更新,它会检查现有的数据库文件。但是如果你想更新你的数据库,你设置数据库版本并在 onUpgrade() 中提供新版本时更新它并部署每次您的资产文件在数据库中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多