SQlite Query Problems, causing Force Close
I am writing my first application, and I am also trying to incorporate a database, and I am really struggling with it. What I am trying to do is have multiple spinners, and those spinners get their data from a database. Each spinner will do a different query.
So far this is what I have: DBUtility
import android.content.Context;
import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import android.database.sqlite.SQLiteDatabase.CursorFactory; import android.widget.SimpleCursorAdapter;
public class DbUtility {
static final String DB_NAME="food";
static final String BEEF_TABLE="beef";
static final String CHICKEN_TABLE="chicken";
SQLiteDatabase db=null;
Context context;
public static class DatabaseHelper extends SQLiteOpenHelper
{
public DatabaseHelper(Context context, String name, CursorFactory factory, int version)
{
super(context, name, factory, version);
// TODO Auto-generated constructor stub
}
@Override
public void onCreate(SQLiteDatabase db)
{
db.execSQL("CREATE TABLE IF NOT EXISTS "+BEEF_TABLE+" (_id INT PRIMARY KEY, cookTime INT PRIMARY KEY ,name VARCHAR);");
db.execSQL("INSERT INTO "+BEEF_TABLE+" values(5000,'Skirt Steak');");
db.execSQL("INSERT INTO "+BEEF_TABLE+" values(10000,'Flank Steak');");
db.execSQL("INSERT INTO "+BEEF_TABLE+" values(15000,'Filet Mignon');");
db.execSQL("CREATE TABLE IF NOT EXISTS "+CHICKEN_TABLE+" (_id INT PRIMARY KEY, cookTime INT PRIMARY KEY ,name VARCHAR);");
db.execSQL("INSERT INTO "+CHICKEN_TABLE+" values(5000,'Breast');");
db.execSQL("INSERT INTO "+CHICKEN_TABLE+" values(10000,'Wings');");
db.execSQL("INSERT INTO "+CHICKEN_TABLE+" values(15000,'Burger');");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
public DbUtility(Context context) {
this.context=context;
}
public SimpleCursorAdapter getBeefAdapter()
{
DatabaseHelper dbhelper=new DatabaseHelper(this.context, DB_NAME, null, 1);
db=dbhelper.getWritableDatabase();
Cursor beefCursor=db.rawQuery("SELECT * FROM "+BEEF_TABLE, null);
while(!beefCursor.isLast())
beefCursor.moveToNext(); //I don't understand why but it's necessary (alternative call c.getCount() )
String[] from=new String[1];
from[0]="name";
int[] to=new int[1];
to[0]=android.R.id.text1;
SimpleCursorAdapter beefAdapter=new SimpleCursorAdapter(this.context, android.R.layout.simple_spinner_item, beefCursor, from, to);
beefAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
db.close();
return beefAdapter;
}
public SimpleCursorAdapter getChickenAdapter()
{
DatabaseHelper dbhelper=new DatabaseHelper(this.context, DB_NAME, null, 1);
db=dbhelper.getWritableDatabase();
Cursor chickenCursor=db.rawQuery("SELECT * FROM "+CHICKEN_TABLE, null);//If I change this to BEEF_TABLE it doesn't force close...
while(!chickenCursor.isLast())
chickenCursor.moveToNext(); //I don't understand why but it's necessary (alternative call c.getCount() )
String[] from=new String[1];
from[0]="name";
int[] to=new int[1];
to[0]=android.R.id.text1;
SimpleCursorAdapter chickenAdapter=new SimpleCursorAdapter(this.context, android.R.layout.simple_spinner_item, chickenCursor, from, to);
chickenAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
db.开发者_开发问答close();
return chickenAdapter;
}
}
and I also have my chickenActivity, this is where my spinners are:
package com.tsilo.grillbuddy;
import android.app.Activity; import android.os.Bundle; import android.widget.SimpleCursorAdapter; import android.widget.Spinner;
public class ChickenActivity extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.spinner);
DbUtility db=new DbUtility(this);
SimpleCursorAdapter beefAdapter=db.getBeefAdapter();
Spinner beefSpinner=(Spinner)this.findViewById(R.id.spinner);
beefSpinner.setAdapter(beefAdapter);
SimpleCursorAdapter chickenAdapter=db.getChickenAdapter();
Spinner chickenSpinner=(Spinner)this.findViewById(R.id.spinner2);
chickenSpinner.setAdapter(chickenAdapter);
}
}
This is what I have noticed:
If I change my getChickenAdapter() so it queries BEEF_TABLE, it works, it is only when I switch it to CHICKEN_TABLE, that it force closes.My DDMS Error:
12-06 16:03:12.473: INFO/Database(11856): sqlite returned: error code = 1, msg = no such table: chicken 12-06 16:03:12.473: DEBUG/AndroidRuntime(11856): Shutting down VM 12-06 16:03:12.473: WARN/dalvikvm(11856): threadid=1: thread exiting with uncaught exception (group=0x4001d7f0) 12-06 16:03:12.483: ERROR/AndroidRuntime(11856): FATAL EXCEPTION: main 12-06 16:03:12.483: ERROR/AndroidRuntime(11856): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.tsilo.grillbuddy/com.tsilo.grillbuddy.ChickenActivity}: android.database.sqlite.SQLiteException: no such table: chicken: , while compiling: SELECT * FROM chicken
I'm wondering if DatabaseHelper.onCreate()
is being called when you run the app. If you're not sure, then set a breakpoint there and see. If it isn't being called, then an older version of your database is in use, and perhaps that version doesn't have the "chicken" table. Try uninstalling the app and running it again (it'll be installed automatically.)
If that turns out to be the issue, you might want to move any future CREATE TABLE IF NOT EXISTS calls into a common method that would be invoked from both onCreate
and onUpgrade
, and be sure to increment your DB version numbers as you do so.
精彩评论