SQLite database won't use WHERE properly? - java

The purpose of this app is to get workouts from a database based on what the user selects, and put them into a textview in a fragmented class. The user can select their experience and if they want to use weights. The database stores all the workouts associated with the experience and weights. For example, in my database I may have a workout that has ( "beginner","no weights", "inclined pushups"). At the end of the app, the database should researched for values that the user selected. For example, it should only find database entries that have beginner if that's what the user choice. I want the database to only return the workout. I am using Android Studio for this, and created the database (as well as populated it), but I keep getting the same error. The first method below is in another class that should get the workout by experience and weight preference in the database.
public ArrayList<String> getWorkoutByBeginnerAndNoWeights(){
Cursor cursor = database.query(MySQLiteHelper.TABLE_EXERCISES, workoutColumns, MySQLiteHelper.COLUMN_EXPERIENCE + "=" + "beginner" + "AND" + "" + MySQLiteHelper.COLUMN_EQUIPMENT + "=" + "no weights", null, null, null, null);
while(!cursor.isLast()){
int i=0;
String workouts =cursor.getString(i++);
workoutArray.add(workouts);
}
//return string array
return workoutArray;
}
----------
Class for making the database
public class MySQLiteHelper extends SQLiteOpenHelper {
public static final String TABLE_EXERCISES = "exercises";
public static final String COLUMN_ID = "_id";
public static final String COLUMN_EXPERIENCE = "experience";
public static final String COLUMN_EQUIPMENT = "equipment";
public static final String COLUMN_WORKOUT = "workout";
public static final String DATABASE_NAME = "exercises.db";
private static final int DATABASE_VERSION = 1;
// Database creation sql statement
private static final String DATABASE_CREATE = "create table "
+ TABLE_EXERCISES + "(" + COLUMN_ID
+ " integer primary key autoincrement, "+ COLUMN_EXPERIENCE + " text not null, " + COLUMN_EQUIPMENT
+ " text not null, "+ COLUMN_WORKOUT
+ " text not null);";
public MySQLiteHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase database) {
database.execSQL(DATABASE_CREATE);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.w(MySQLiteHelper.class.getName(),
"Upgrading database from version " + oldVersion + " to "
+ newVersion + ", which will destroy all old data");
db.execSQL("DROP TABLE IF EXISTS " + TABLE_EXERCISES);
onCreate(db);
}
}
-------
Code in fragment to display it as a text using textView
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View inf = inflater.inflate(R.layout.fragment_test, container, false);
TextView tv = (TextView) inf.findViewById(R.id.testText);
tv.setText(MainActivity.dataSource.getWorkoutByBeginnerAndNoWeights().toString());
// Inflate the layout for this fragment
return inf;
}
----------
error I am getting
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.hfad.workoutmaker, PID: 20245
android.database.sqlite.SQLiteException: no such column: beginner (code 1): , while compiling: SELECT _id, workout FROM exercises WHERE experience=beginner
at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:889)
at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:500)
at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588)
at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:58)
at android.database.sqlite.SQLiteQuery.<init>(SQLiteQuery.java:37)
at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:44)
at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1318)
at android.database.sqlite.SQLiteDatabase.queryWithFactory(SQLiteDatabase.java:1165)
at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1036)
at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1204)
at com.hfad.workoutmaker.WorkoutsDataSource.getWorkoutByBeginnerAndNoWeights(WorkoutsDataSource.java:74)
at com.hfad.workoutmaker.TestFragment.onCreateView(TestFragment.java:41)
at androidx.fragment.app.Fragment.performCreateView(Fragment.java:2698)
at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:320)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1187)
at androidx.fragment.app.FragmentManager.addAddedFragments(FragmentManager.java:2224)
at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:1997)
at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:1953)
at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:1849)
at androidx.fragment.app.FragmentManager$4.run(FragmentManager.java:413)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)

You should always use 'beginner' not beginner as your value.
So a simple SQL statement should look like this:
SELECT * FROM `Table` WHERE `ID`='1'

Related

Android search query returning null list

For my app I am using an sqllite database to make a movie logging app. A movie object has the title, a boolean for whether the user has already seen the movie or not and whether they have it on their watchlist
I am able to add a movie to the sqllite database, but when I run a search query to return a list of Movie object, I try get a null pointer exception when I try to display the results in a Listview.
This is my movie object's variable types
public class Movie implements Serializable {
private String movieTitle;
private boolean seen; //true if user has seen movie
private boolean addToWatchlist; //if user wants to add movie to watchlist
This is my table and ts fields
#Override
public void onCreate(SQLiteDatabase db) {
String CREATE_MOVIE_TABLE = "CREATE TABLE " + MOVIE_TABLE + "("
+ KEY_ID + " INTEGER PRIMARY KEY," + KEY_TITLE + " TEXT,"
+ KEY_SEEN + " INT," + KEY_WATCHLIST + " INT " + ")";
db.execSQL(CREATE_MOVIE_TABLE);
}
My addMovie method
public void addMovie(Movie m) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(KEY_TITLE, m.getmMovieTitle());
if (m.isSeen()) {
values.put(KEY_SEEN, 1);
}
else {values.put(KEY_SEEN,0);}
if (m.isAddWatchlist()) {
values.put(KEY_WATCHLIST, 1);
}
else {values.put(KEY_WATCHLIST,0);}
System.out.println(values.toString());
db.insert(MOVIE_TABLE, null, values);
db.close();
And the Select Query which is the source of all my problems. Resulting in a null list even after adding movies that have been seen, where I set seen = 1;
public ArrayList<Movie> getSeenMovies(){
ArrayList<Movie> seenList = new ArrayList<Movie>();
String selectQuery = "SELECT * FROM " + MOVIE_TABLE + " WHERE " + KEY_SEEN + " == " +1;
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
if (cursor != null && cursor.moveToFirst()) {
do {
Movie m = new Movie();
m.setMovieTitle(cursor.getString(1));
m.setSeen(true);
m.setAddWatchlist(Integer.parseInt(cursor.getString(3)) == 1);
seenList.add(m);
}
while (cursor.moveToNext());
}
return seenList;
}
The NullPointerException comes when I try to populate my listview with the query results because of the movieList.size() in the getCount method of my MovieArrayAdapter class which says my movieList is null
MovieArrayAdapter
public class MovieArrayAdapter extends BaseAdapter {
private Context context;
private ArrayList<Movie> movieList;
//adapter constructor
public MovieArrayAdapter(Context context, ArrayList<Movie> movieList) {
this.context = context;
this.movieList = movieList;
}
//abstract method returns size of movie list
public int getCount() {
return this.movieList.size();
}
//abstract method returns item at input position in list
public Object getItem(int pos){return this.movieList.get(pos);}
// abstract method gets item id at position i
public long getItemId(int pos){return pos;}
public View getView(int position, View convertView, ViewGroup parent){
View v = View.inflate(context, R.layout.movie_list_entry, null);
//finds MovieTitle textview field in the movie_list entry layout file
TextView title = (TextView)v.findViewById(R.id.MovieTitle);
//sets MovieTitle field to title of movie from list
title.setText(movieList.get(position).getmMovieTitle());
return v;}
}
The error:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.indiana.kupshah.movdex, PID: 4754
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.indiana.kupshah.movdex/com.indiana.kupshah.movdex.SeenList}: java.lang.NullPointerException: Attempt to invoke virtual method 'int java.util.ArrayList.size()' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2646)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2707)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1460)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6077)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'int java.util.ArrayList.size()' on a null object reference
at com.indiana.kupshah.movdex.MovieArrayAdapter.getCount(MovieArrayAdapter.java:32)
at android.widget.ListView.setAdapter(ListView.java:493)
at com.indiana.kupshah.movdex.SeenList.onCreate(SeenList.java:27)
at android.app.Activity.performCreate(Activity.java:6662)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2599)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2707) 
at android.app.ActivityThread.-wrap12(ActivityThread.java) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1460) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:154) 
at android.app.ActivityThread.main(ActivityThread.java:6077) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755) 
DBHandler movdexDB = new DBHandler(this); is an instance variable for the add movie form
This adds movie to the db when add button is clicked
public void onAddButtonClick(View v){
EditText movieTitle = (EditText) findViewById(R.id.TitleText);
CheckBox seen = (CheckBox) findViewById(R.id.SeenCheck);
CheckBox watch = (CheckBox) findViewById(R.id.WatchCheck);
//converts View values to types suitable for Movie class
String addTitle = movieTitle.getText().toString();
Boolean addSeen = seen.isChecked();
Boolean addWatch = watch.isChecked();
Movie movie = new Movie (addTitle,addSeen,addWatch);
movdexDB.addMovie(movie);
}
This is the button click that starts the SeenList Activity
public void onSeenButtonClick(View v){
Intent myIntent = new Intent(AddMovieEntry.this,SeenList.class);
myIntent.putExtra("seen_list", movdexDB.getSeenMovies());
startActivity(myIntent);
}
And lastly, the SeenList onCreate method
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_seen_list);
//finds list view and populates from movies from the seen list,
//using the layout established in the MovieAdapter arrayadapter class
ListView SeenListView = (ListView) findViewById(R.id.SeenList);
Intent i = getIntent();
ArrayList<Movie> seenList;
//sets the list of seen and watched movies
seenList = (ArrayList<Movie>) i.getSerializableExtra("seenlist_movies");
MovieArrayAdapter myAdapter = new MovieArrayAdapter(this, seenList);
SeenListView.setAdapter(myAdapter);
}
Looks like you just need to protect access for null values in MovieArrayAdapter:
public int getCount(){
return movieList != null ? movieList.size() : 0;
}

SQLite DB table not created in Android while DB created

I am working towards creating an Android app. I am beginner in Android and Java application development while I have good experience of web development.
I am trying to create a DB and then creating my first table in SQLite. It is creating DB but not DB table.
I have created Contaract class.
package com.haafiz.project;
import android.provider.BaseColumns;
public final class ProjectContaract {
public ProjectContaract(){}
public static abstract class Site implements BaseColumns{
public static final String TABLE_NAME = "site";
public static final String COLUMN_NAME_SITE_NAME = "site_name";
public static final String COLUMN_NAME_LOGIN = "login_name";
public static final String COLUMN_NAME_HOST = "host";
public static final String COLUMN_NAME_PASSWORD = "password";
}
}
And then DB helper class.
package com.haafiz.project;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class DBHelper extends SQLiteOpenHelper {
private static final String TEXT_TYPE = " TEXT";
private static final String COMMA_SEP = ",";
private static final String SQL_CREATE_ENTRIES =
"CREATE TABLE " + ProjectContaract.Site.TABLE_NAME + " (" +
projectContaract.Site._ID + " INTEGER PRIMARY KEY," +
projectContaract.Site.COLUMN_NAME_SITE_NAME + TEXT_TYPE + COMMA_SEP +
projectContaract.Site.COLUMN_NAME_LOGIN + TEXT_TYPE + COMMA_SEP +
projectContaract.Site.COLUMN_NAME_HOST + TEXT_TYPE + COMMA_SEP +
projectContaract.Site.COLUMN_NAME_PASSWORD + TEXT_TYPE + " )";
private static final String SQL_DELETE_ENTRIES =
"DROP TABLE IF EXISTS " + ProjectContaract.Site.TABLE_NAME;
public static final int DATABASE_VERSION = 1;
public static final String DATABASE_NAME = "Project";
public DBHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(SQL_CREATE_ENTRIES);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion){
db.execSQL(SQL_DELETE_ENTRIES);
onCreate(db);
}
#Override
public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
onUpgrade(db, oldVersion, newVersion);
}
}
And here my main activity using that DB Helper as below:
package com.haafiz.project;
import android.app.Activity;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
projectDBHelper dbHelper = new projectDBHelper(getApplicationContext());
// Gets the data repository in read mode
SQLiteDatabase db = dbHelper.getWritableDatabase();
// Projection that specifies which columns from the database
String[] projection = {
projectContaract.Site._ID,
projectContaract.Site.COLUMN_NAME_SITE_NAME,
projectContaract.Site.COLUMN_NAME_LOGIN,
projectContaract.Site.COLUMN_NAME_HOST,
projectContaract.Site.COLUMN_NAME_PASSWORD
};
// How you want the results sorted in the resulting Cursor
String sortOrder =
projectContaract.Site.COLUMN_NAME_SITE_NAME + " DESC";
Cursor c = db.query(
projectContaract.Site.TABLE_NAME, // The table to query
projection, // The columns to return
null, // The columns for the WHERE clause
null, // The values for the WHERE clause
null, // don't group the rows
null, // don't filter by row groups
sortOrder // The sort order
);
setContentView(R.layout.activity_main);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
DB is being created but table is not, I check that with adb shell attach with emulator. What am I doing wrong? The table is not being created.
And an important thing is that I am not getting errors related to this in log.
But in logcat with "no filter" in drop down where it was "show only selected application" previously and with "sql" in filter search box, it shows following messages in log cat:
08-04 00:41:35.494 403-474/android.process.media V/MediaScanner﹕ pruneDeadThumbnailFiles... android.database.sqlite.SQLiteCursor#41302da8
08-04 00:41:35.494 403-474/android.process.media V/MediaScanner﹕ /pruneDeadThumbnailFiles... android.database.sqlite.SQLiteCursor#41302da8
08-04 00:54:02.685 623-632/com.haafiz.project E/SQLiteDatabase﹕ close() was never explicitly called on database '/data/data/com.haafiz.project/databases/project'
android.database.sqlite.DatabaseObjectNotClosedException: Application did not close the cursor or database object that was opened here
at android.database.sqlite.SQLiteDatabase.<init>(SQLiteDatabase.java:1943)
at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:1007)
at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:986)
at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:1051)
at android.app.ContextImpl.openOrCreateDatabase(ContextImpl.java:770)
at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:221)
at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:157)
at com.haafiz.project.MainActivity.onCreate(MainActivity.java:20)
at android.app.Activity.performCreate(Activity.java:4466)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1920)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1981)
at android.app.ActivityThread.access$600(ActivityThread.java:123)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1147)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4424)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
at dalvik.system.NativeStart.main(Native Method)
08-04 00:54:02.766 623-632/com.haafiz.project E/System﹕ java.lang.IllegalStateException: Don't have database lock!
at android.database.sqlite.SQLiteDatabase.verifyLockOwner(SQLiteDatabase.java:2090)
at android.database.sqlite.SQLiteDatabase$1.entryRemoved(SQLiteDatabase.java:2182)
at android.database.sqlite.SQLiteDatabase$1.entryRemoved(SQLiteDatabase.java:2178)
at android.util.LruCache.trimToSize(LruCache.java:197)
at android.util.LruCache.evictAll(LruCache.java:285)
at android.database.sqlite.SQLiteDatabase.deallocCachedSqlStatements(SQLiteDatabase.java:2143)
at android.database.sqlite.SQLiteDatabase.closeClosable(SQLiteDatabase.java:1126)
at android.database.sqlite.SQLiteDatabase.finalize(SQLiteDatabase.java:1914)
at java.lang.Daemons$FinalizerDaemon.doFinalize(Daemons.java:182)
at java.lang.Daemons$FinalizerDaemon.run(Daemons.java:168)
at java.lang.Thread.run(Thread.java:856)
Other than first two lines, other lines in output of log cat, all other lines are highlighted in red color.
Seems like the database didn't get closed correctly. Sometimes this can happen during development when you are often reinstalling builds of the app.
Uninstall the app and reinstall it. Alternatively open Settings > Apps > [your app] and tap the Clear Data button. Either of these will remove the existing database file so the next attempt to open it will create a new one.
SQLLite operates in many modes, one of which is that everything is stored in memory and not flushed to disk unless certain conditions are met (like high mem usage or db being closed). You are not closing the db which is why you are not able to see the tables in the sqlite file.
For your example to work, store dbHelper as a class property, assign new object to it when activity initializes, and then close it before the activity is closed/destroyed. That should solve your issue.
You're missing a semicolon at the end of your create table SQL statement. Also, your primary key should be autoincrement.
private static final String SQL_CREATE_ENTRIES =
"CREATE TABLE " + ProjectContaract.Site.TABLE_NAME + " (" +
projectContaract.Site._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
projectContaract.Site.COLUMN_NAME_SITE_NAME + TEXT_TYPE + COMMA_SEP +
projectContaract.Site.COLUMN_NAME_LOGIN + TEXT_TYPE + COMMA_SEP +
projectContaract.Site.COLUMN_NAME_HOST + TEXT_TYPE + COMMA_SEP +
projectContaract.Site.COLUMN_NAME_PASSWORD + TEXT_TYPE + " );";

SQLite Android RunTimeError

I am trying to follow this tutorial (Part 3) about getting SQLite Database to work with Android application. I've made some changes to the content but the code should be the same. The android application crashes after it opens without displaying anything and this is the output from LogCat:
11-25 11:42:43.281: E/AndroidRuntime(1098): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.munroproject/com.example.munroproject.MainActivity}: android.database.sqlite.SQLiteException: near "drop": syntax error (code 1): , while compiling: CREATE TABLE munro (_id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, area TEXT, height TEXT, grid TEXT, drop TEXT, feature TEXT, country TEXT, geographurl TEXT, latitude TEXT, longitude TEXT)
and this is the contents of the database helper:
package com.example.munroproject;
import android.content.ContentValues;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class DatabaseHelper extends SQLiteOpenHelper{
public static final String DATABASE_NAME = "munro_directory";
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, 1);
}
public void onCreate(SQLiteDatabase db){
String sql = "CREATE TABLE munro (" +
"_id INTEGER PRIMARY KEY AUTOINCREMENT, " +
"name TEXT, " +
"area TEXT, " +
"height TEXT, " +
"grid TEXT, " +
"drop TEXT, " +
"feature TEXT, " +
"country TEXT, " +
"geographurl TEXT, " +
"latitude TEXT, " +
"longitude TEXT)";
db.execSQL(sql);
ContentValues values = new ContentValues();
String inputvalue = "Ben Chonzie,Loch Tay to Perth,931,NN773308,645,cairn/shelter,S,NN7732430857,56.453851,-3.992057");
String[] msplit = inputvalue.split(",");
int j=0;
values.put("name",msplit[j++]);
values.put("area",msplit[j++]);
values.put("height",msplit[j++]);
values.put("grid",msplit[j++]);
values.put("drop",msplit[j++]);
values.put("feature",msplit[j++]);
values.put("country",msplit[j++]);
values.put("geograph",msplit[j++]);
values.put("latitute",msplit[j++]);
values.put("longitude",msplit[j++]);
db.insert("munro", "name", values);
}
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion){
db.execSQL("DROP TABLE IF EXISTS munro");
onCreate(db);
}
}
And the mainActivity file looks like this:
package com.example.munroproject;
import android.os.Bundle;
import android.app.Activity;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.view.View;
import android.widget.EditText;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
public class MainActivity extends Activity {
protected EditText searchText;
protected SQLiteDatabase db;
protected Cursor cursor;
protected ListAdapter adapter;
protected ListView munroList;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
db = (new DatabaseHelper(this)).getWritableDatabase();
searchText = (EditText) findViewById (R.id.searchText);
munroList = (ListView) findViewById (R.id.list);
}
#SuppressWarnings("deprecation")
public void search(View view) {
// || is the concatenation operation in SQLite
cursor = db.rawQuery("SELECT _id, name, height, region FROM munro WHERE name || ' ' || height LIKE ?",
new String[]{"%" + searchText.getText().toString() + "%"});
adapter = new SimpleCursorAdapter(this,R.layout.munro_list_item,cursor,new String[] {"name", "height", "region"},new int[] {R.id.name, R.id.height, R.id.region});
munroList.setAdapter(adapter);
}
Any suggestions ?
"drop" is a reserved keyword in SQLite used to drop (or delete) tables. If you really want to use it, you can, by enclosing it in double quotes. See example below
CREATE TABLE "[tablename]" ("drop" text)
In sqlite INTEGER PRIMARY KEY is Autoincrement by default no need to specify INTEGER PRIMARY KEY AUTOINCREMENT In addition sql has inbuilt command drop so change the column/attribute name

Eclipse inserting data into SQLite Database, no such table

I'm trying to insert data into the database but it tells me there's no such table. I also have another sqlite database inside the application, i'm not sure if that affects this one, but I don't think so. It uses the same database name, but a different table name. If you think it does affect it, tell me and I'll post up the code for that too.
The logcat gives me these messages:
(1) no such table: notes
Error inserting title=Bleh desc=bleh
android.database.sqlite.SQLiteException: no such table: notes (code 1): , while compiling: INSERT INTO notes(title,desc) VALUES (?,?)
at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:889)
at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:500)
at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588)
at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:58)
at android.database.sqlite.SQLiteStatement.<init>(SQLiteStatement.java:31)
at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1467)
at android.database.sqlite.SQLiteDatabase.insert(SQLiteDatabase.java:1339)
at com.example.stepsaway.NoteActivity.addEntry(NoteActivity.java:102)
at com.example.stepsaway.NoteActivity.onClick(NoteActivity.java:75)
at android.view.View.performClick(View.java:4240)
at android.view.View$PerformClick.run(View.java:17721)
at android.os.Handler.handleCallback(Handler.java:730)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5103)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
at dalvik.system.NativeStart.main(Native Method)
The Activity java is:
public class NoteActivity extends Activity implements OnClickListener {
Button buttonLeaveNote;
private EditText mTitle;
private EditText mDesc;
protected NoteDBHelper noteDB = new NoteDBHelper(NoteActivity.this);
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_note);
buttonLeaveNote = (Button) findViewById(R.id.buttonLeaveNote);
buttonLeaveNote.setOnClickListener(this);
mTitle = (EditText)findViewById(R.id.etitle);
mDesc = (EditText)findViewById(R.id.edesc);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.note, menu);
return true;
}
#Override
public void onClick(View v) {
switch(v.getId()){
case R.id.buttonLeaveNote:
String title = mTitle.getText().toString();
String desc = mDesc.getText().toString();
boolean invalid = false;
if(title.equals(""))
{
invalid = true;
Toast.makeText(getApplicationContext(), "Please enter a title", Toast.LENGTH_SHORT).show();
}
else
if(desc.equals(""))
{
invalid = true;
Toast.makeText(getApplicationContext(), "Please enter description", Toast.LENGTH_SHORT).show();
}
else
if(invalid == false)
{
addEntry(title, desc);
Intent i_note = new Intent(NoteActivity.this, JustWanderingActivity.class);
startActivity(i_note);
//finish();
}
break;
}
}
public void onDestroy()
{
super.onDestroy();
noteDB.close();
}
private void addEntry(String title, String desc)
{
SQLiteDatabase notedb = noteDB.getWritableDatabase();
ContentValues values = new ContentValues();
values.put("title", title);
values.put("desc", desc);
//values.put("lati", lati);
//values.put("lng", lng);
try
{
long newRowId;
newRowId = notedb.insert(NoteDBHelper.DATABASE_TABLE_NAME, null, values);
Toast.makeText(getApplicationContext(), "Note successfully added", Toast.LENGTH_SHORT).show();
}
catch(Exception e)
{
e.printStackTrace();
}
}
public void onNothingSelected(AdapterView<?> arg0) {
// TODO Auto-generated method stub
}
}
And the Database java is:
public class NoteDBHelper extends SQLiteOpenHelper
{
private SQLiteDatabase notedb;
public static final String NOTE_ID = "_nid";
public static final String NOTE_TITLE = "title";
public static final String NOTE_DESC = "desc";
public static final String NOTE_LAT = "lati";
public static final String NOTE_LONG = "lng";
NoteDBHelper noteDB = null;
private static final String DATABASE_NAME = "stepsaway.db";
private static final int DATABASE_VERSION = 2;
public static final String DATABASE_TABLE_NAME = "notes";
private static final String DATABASE_TABLE_CREATE =
"CREATE TABLE " + DATABASE_TABLE_NAME + "(" +
"_nid INTEGER PRIMARY KEY AUTOINCREMENT," +
"title TEXT NOT NULL, desc LONGTEXT NOT NULL);";
public NoteDBHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
System.out.println("In constructor");
}
#Override
public void onCreate(SQLiteDatabase notedb) {
try{
notedb.execSQL(DATABASE_TABLE_CREATE);
}catch(Exception e){
e.printStackTrace();
}
}
#Override
public void onUpgrade(SQLiteDatabase notedb, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
}
public Cursor rawQuery(String string, String[] strings) {
// TODO Auto-generated method stub
return null;
}
public void open() {
getWritableDatabase();
}
public Cursor getDetails(String text) throws SQLException
{
Cursor mCursor =
notedb.query(true, DATABASE_TABLE_NAME,
new String[]{NOTE_ID, NOTE_TITLE, NOTE_DESC},
NOTE_TITLE + "=" + text,
null, null, null, null, null);
if (mCursor != null)
{
mCursor.moveToFirst();
}
return mCursor;
}
}
Any help would be appreciated, thank you.
Edit: Looks like the problem is creating a second table within the same database name. It won't let me create a second one. The first time creating the DB works fine, but it gives the SQLite Exception with no such table when trying to create another table. Is there some code I need to alter or add to create a second table? Because all i did was create another sqlite database java with the same DATABASE_NAME, but a different DATABASE_TABLE_NAME.
My best guess is when you create nodeDB object, the activity is still not available. Therefore you will failed creating the table.
You can try moving how you initialise the noteDB into inside onCreate():
protected NoteDBHelper noteDB;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_note);
noteDB = new NoteDBHelper(NoteActivity.this);
buttonLeaveNote = (Button) findViewById(R.id.buttonLeaveNote);
buttonLeaveNote.setOnClickListener(this);
mTitle = (EditText)findViewById(R.id.etitle);
mDesc = (EditText)findViewById(R.id.edesc);
}
Your onUpgrade() is empty and database schema version is 2. My guess is that your initial version of the database didn't have the notes table and when it was later added, the empty upgrade code couldn't add it. But SQLiteOpenHelper is satisfied as it is now running version 2 of the database.
To fix it once, clean your app data. E.g. in settings app, go to manage apps -> downloaded -> select your app and click on the "Clear application data" button. Or just uninstall and reinstall the app. This approach is good enough during development.
To fix it for released versions, implement onUpgrade() so that is updates the database schema and does any necessary data migration. If you're not concerned about data loss, you can just call DROP TABLE on the old tables and then call onCreate() to recreate the tables.
To your follow-up question regarding multiple tables: Just use the same helper class to manage the database. One helper per database file. Create all tables in onCreate() and do any required migrations in onUpgrade().
Regarding to First issue : as I explained in my comment >
If you have created the DB before and adding a table afterwards this can cause the problem. Tables are created for the first time DB created. So uninstall or clean the data in the app from device and run it again.
For the Second Issue :
If you want to Create a table, do the same that you are already doing for the table you have.
#Override
public void onCreate(SQLiteDatabase notedb) {
try{
notedb.execSQL(DATABASE_TABLE_CREATE);
notedb.execSQL(DATABASE_TABLE_CREATE_STRING_2);
}catch(Exception e){
e.printStackTrace();
}
}

Adding Information in SQLite

I am having trouble with my Android App when adding information into SQLite. I am relatively new to Java/SQLite and though I have followed a lot of tutorials on SQLite and have been able to get the example code to run I am unable to get tables to be created and data to import when running my own app. I have included my code in two Java files Questions (Main Program) and QuestionData (helper class represents the database).
Questions.java:
public class Questions extends Activity {
private QuestionData questions;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.quiztest);
questions = new QuestionData(this);
try {
Cursor cursor = getQuestions();
showQuestions(cursor);
} finally {
questions.close();
}
}
private Cursor getQuestions() {
//Select Query
String loadQuestions = "SELECT * FROM questionlist";
SQLiteDatabase db = questions.getReadableDatabase();
Cursor cursor = db.rawQuery(loadQuestions, null);
startManagingCursor(cursor);
return cursor;
}
private void showQuestions(Cursor cursor) {
// Collect String Values from Query and Display them this part of the code is wokring fine when there is data present.
QuestionData.java
public class QuestionData extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "TriviaQuiz.db" ;
private static final int DATABASE_VERSION = 2;
public QuestionData(Context ctx) {
super(ctx, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE questionlist (_id INTEGER PRIMARY KEY AUTOINCREMENT, QID TEXT, QQuestion TEXT, QAnswer TEXT, QOption1 TEXT, QOption2 TEXT, QOption3 TEXT, QCategoryTagLvl1 TEXT, QCategoryTagLvl2 TEXT, QOptionalTag1 TEXT, QOptionalTag2 TEXT, QOptionalTag3 TEXT, QOptionalTag4 TEXT, QOptionalTag5 TEXT, QTimePeriod TEXT, QDifficultyRating TEXT, QGenderBias TEXT, QAgeBias TEXT, QRegion TEXT, QWikiLink TEXT, QValidationLink1 TEXT, QValidationLink2 TEXT, QHint TEXT, QLastValidation TEXT, QNotes TEXT, QMultimediaType TEXT, QMultimediaLink TEXT, QLastAsked TEXT);");
db.execSQL("INSERT INTO questionlist (_id, QID, QQuestion, QAnswer, QOption1, QOption2, QOption3, QCategoryTagLvl1, QCategoryTagLvl2, QOptionalTag1, QOptionalTag2, QOptionalTag3, QOptionalTag4, QOptionalTag5, QTimePeriod, QDifficultyRating, QGenderBias, QAgeBias, QRegion, QWikiLink, QValidationLink1, QValidationLink2, QHint, QLastValidation, QNotes, QMultimediaType, QMultimediaLink, QLastAsked)"+
"VALUES (null,'Q00001','Example','Ans1','Q1','Q2','Q3','Q4','','','','','','','','','','','','','','','','','','','','')");
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion,
int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
onCreate(db);
}
}
Any suggestions at all would be great. I have tried debugging which suggests that the database does not exist. Thanks in advance for your assistance.
I removed the constants setup which had a capitalisation in it which was not referenced elsewhere. I knew it was going to be something simple but I could not locate the issue. Thanks again!

Categories

Resources