【问题标题】:SQLite database Query AndroidSQLite 数据库查询 Android
【发布时间】:2014-05-28 08:33:59
【问题描述】:

我在我的 Android 应用上查询 SQLite 数据库时遇到问题。我使用this tutorial 来设置我的数据库助手类。

我做了一个简单的查询函数:

public Cursor queryDB(String Query,String[] args){  

Cursor cursor = myDataBase.rawQuery(Query, args);

return cursor;

然后我这样称呼它:

 String[] testarg = {"Denver Bake"};
 myDataBase.getReadableDatabase();
 Cursor results = myDataBase.queryDB("SELECT * FROM Recipes WHERE r_name = ?", testarg);

我得到的错误是:

 E/AndroidRuntime(30483): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.dbtest/com.example.dbtest.MainActivity}: android.database.sqlite.SQLiteException: no such table: Recipes: , while compiling: SELECT * FROM Recipes WHERE r_name = ?

我知道Recipes 表确实存在于我的数据库中,因为它出现在本教程的SQLite 数据库浏览器中。我已经尝试了教程 cmets 中的一些建议,但我仍然遇到同样的错误,我不确定现在该怎么做。

先谢谢了。

这是我的创作

public void createDataBase() throws IOException{
    boolean dbExist = checkDataBase();
    if(dbExist){
            //do nothing - database already exist
    }else{

        this.getReadableDatabase();
        try {
            copyDataBase();
            } catch (IOException e) {

            throw new Error("Error copying database");
            }
    }
}

这是我的复制代码:

private void copyDataBase() throws IOException{
    //Open your local db as the input stream
    InputStream myInput = myContext.getAssets().open(DB_NAME);
    // Path to the just created empty db
    String outFileName = DB_PATH + DB_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();
}

最后,我的资产文件夹中确实有我的数据库。错误信息告诉我数据库中的表不存在。

【问题讨论】:

  • 发布您的创建表查询。
  • 你必须在浏览器中创建你自己的sqlite数据库。并将这个数据库复制到你项目的assets文件夹中。
  • 阅读错误信息!正如它(和@dipali)所说,您没有创建数据库。以下来自@krishanDhamat 的答案显示了您应该做什么:使用 SQLiteOpenHelper。您需要在其他地方阅读,以了解原因...
  • 显然,您没有正确复制数据库。显示从资产文件夹复制数据库的代码。

标签: android sqlite


【解决方案1】:

您必须在浏览器中创建自己的 SQLite 数据库,并将此数据库复制到项目的 assets 文件夹中:

  1. 在浏览器中创建数据库。
  2. 复制数据库
  3. 粘贴到您的资产文件夹中。
  4. 创建一些扩展 SQLiteOpenHelper 类的 dbhelper 类,并将数据库从 assets 文件夹中复制出来,以便应用可以访问它:
public class DbHelper extends SQLiteOpenHelper {

    // The Android's default system path of your application database.
    private static String PACKAGENAME = "com.SVLL";
    private static String DB_PATH = "/data/data/" + PACKAGENAME + "/databases/";
    private static String DB_NAME = "SVLL.sqlite";

    private static final String TAG = "DbHelper";
    private SQLiteDatabase myDataBase;

    private final Context myContext;

    /**
     * Constructor Takes and keeps a reference of the passed context in order to
     * access to the application assets and resources.
     * 
     * @param context
     */
    public DbHelper(final Context context) {
        super(context, DB_NAME, null, 1);
        this.myContext = context;

    }

    /**
     * Creates a empty database on the system and rewrites it with your own
     * database.
     * */
    public final void createDataBase() throws IOException {

        final boolean dbExist = checkDataBase();
        SQLiteDatabase db_Read = null;
        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.
            // 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.
            // db_Read = this.getReadableDatabase(DB_Internal);
            db_Read = this.getReadableDatabase();
            db_Read.close();

            copyDataBase();

        }
    }

    /**
     * Restore whole database without any data
     * 
     * @throws IOException
     */
    public final void RestoreDatabase() throws IOException {
        SQLiteDatabase db_Read = this.getReadableDatabase();
        db_Read.close();

        copyDataBase();
        Log.i(TAG, "Database REstored");
    }

    /**
     * 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() {
        final File dbFile = new File(DB_PATH + DB_NAME);
        return dbFile.exists();
    }

    /**
     * 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.
     * 
     * @throws IOException
     * */
    private void copyDataBase() throws IOException {

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

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

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

        // transfer bytes from the inputfile to the outputfile
        final 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 final SQLiteDatabase openDataBase() {
        // Open the database
        final String myPath = DB_PATH + DB_NAME;
        if (myDataBase != null && myDataBase.isOpen()) {
            myDataBase.close();
        }
        return myDataBase = SQLiteDatabase.openDatabase(myPath, null,
                SQLiteDatabase.OPEN_READWRITE);

    }

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

    @Override
    public void onCreate(final SQLiteDatabase arg0) {
    }

    @Override
    public void onUpgrade(final SQLiteDatabase arg0, final int arg1,
            final int arg2) {
    }

}

【讨论】:

    【解决方案2】:

    CL 非常正确。我的复制代码是正确的,它没有被正确调用。我最终做的是草率,但我从查询代码而不是我的创建数据库中调用了 copyDataBase()。我知道愚蠢和低效,但它现在有效。

    【讨论】:

      【解决方案3】:

      试试这个:

      public class DBAdapter {
      
      private static final String TAG = "[ DBAdapter ]";  
      private static final String KEY_TOU_ID = "tournamentid";    
      private static final String KEY_TEAM_ID = "teamid"; 
      private static final String KEY_INNINGS_ID = "inningsid";
      private static final int DATABASE_VERSION = 1;
      private static final String DATABASE_NAME = "YourDbName";   
      private static final String INNINGS_LIST_TABLE = "inningslist";
      
      
      
      private static final String INNINGS_TABLE = "create table "
              + INNINGS_LIST_TABLE + "(" + KEY_INNINGS_ID
              + " integer primary key autoincrement," + KEY_GAME_ID + " integer,"
              + KEY_TEAM_ID + " integer," + KEY_TOU_ID + " integer);";
      
      private DatabaseHelper DBhelper;
      private SQLiteDatabase db;
      private ProgressDialog pd;
      
      public DBAdapter(Context ctx) {
          DBhelper = new DatabaseHelper(ctx);
      }
      
      private static class DatabaseHelper extends SQLiteOpenHelper {
      
          public DatabaseHelper(Context context) {
              super(context, DATABASE_NAME, null, DATABASE_VERSION);
          }
      
          @Override
          public void onCreate(SQLiteDatabase db) {
      
      
      
              Log.i(TAG, "INNINGS TABLE" + INNINGS_LIST_TABLE);
      
              db.execSQL(INNINGS_TABLE);
      
          }
      
          @Override
          public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
              Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
                      + newVersion + ", which will destroy all old data");
              db.execSQL("DROP TABLE IF EXISTS titles");
              onCreate(db);
          }
      }
      
      public DBAdapter open() {
          try {
              db = DBhelper.getWritableDatabase();
          } catch (SQLiteException sql) {
              sql.printStackTrace();
          }
          return this;
      }
      
      public boolean isCreated() {
          if (db != null) {
              return db.isOpen();
          }
      
          return false;
      }
      
      public boolean isOpen() {
          return db.isOpen();
      }
      
      public void close() {
          DBhelper.close();
          db.close();
      }
      

      }

      【讨论】:

      • 非常相关,如果没有很好的解释,解决方案!
      • 这个答案不相关,因为问题是关于使用已经存在的数据库。此外,这个答案没有用,因为它只是一堆没有被调整以适应这个问题的未注释和无法解释的代码。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多