I am trying to create a SQLite database for my Android app.
Everything worked fine until I got to the JUnit Testing for the query function in ContentProvider.
I read the forum very in depth, and saw that some people have the errors below
Create table has typos in it - here's my table creation statement
CREATE TABLE movie (
_id INTEGER PRIMARY KEY,
title TEXT NOT NULL,
overview TEXT DEFAULT 'NO OVERVIEW',
poster_path TEXT DEFAULT 'NO POSTER',
release_date TEXT DEFAULT 'NO DATE AVAILABLE',
vote_average TEXT DEFAULT 'NO VOTES YET',
sort_type INTEGER NOT NULL,
favorite INTEGER DEFAULT 0
);
Not updated Database_Version constant once the column was added.
I tried updating the Database_Version constant and I also tried changing the name of the database, so it is created from scratch.
Deleted all of my old app from my Android device.
Read this post.
I did check for all of the nuances it speaks about.
However, I still have my exception being thrown
android.database.sqlite.SQLiteException: no such column: MovieContract.Movie.favorite (code 1): , while compiling: SELECT * FROM movie WHERE MovieContract.Movie.favorite = ? ORDER BY MovieContract.Movie.title
My testCase method that throws the error.
Error is being thrown on the line Cursor movieCursor...
public void testBasicMovieQuery(){
MovieDBHelper dbHelper = new MovieDBHelper(mContext);
SQLiteDatabase db = dbHelper.getWritableDatabase();
ContentValues movieValues = TestUtilities.createMovieValues();
long recordNum = db.insert(MovieContract.Movie.TABLE_NAME, null,movieValues);
assertTrue("Unable to Insert WeatherEntry into the Database", recordNum != -1);
db.close();
String selection = "MovieContract.Movie.FAVORITE = ?";
String [] selectionArgs = new String [] {"'1'"};
String sortOrder = "MovieContract.Movie.TITLE";
Cursor movieCursor = mContext.getContentResolver().query(
MovieContract.Movie.CONTENT_URI,
null,
selection,
selectionArgs,
sortOrder
);
TestUtilities.validateCursor("testBasicWeatherQuery", movieCursor, movieValues);
movieCursor.close();
}
Here is my query method in my ContentProvider; so when I have 'selection' defined it throws me the 'no such column' but if I put all null, besides the URI it will throw the Unknown Uri exception from the default, even though the Uri actually exists in UriMatcher.
#Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
Cursor cursor;
Log.v("QUERY MovieProvider", uri.toString());
switch (uriMathcher.match(uri)){
case MOVIE_WITH_ID:{
Log.v("MovieProvider QUERY", "MOVIE WITH ID");
//cursor = getMovieWithId(uri);
cursor = dbHelper.getReadableDatabase().query(MovieContract.Movie.TABLE_NAME ,null, "MovieContract.Movie._ID =", selectionArgs,null,null,sortOrder);
}
break;
case MOVIE:{
Log.v("MovieProvider QUERY", "MOVIE");
//Log.v("MovieProvider QUERY", selection);
//Log.v("MovieProvider QUERY", selectionArgs[0]);
cursor = dbHelper.getReadableDatabase().query(MovieContract.Movie.TABLE_NAME, null,selection, selectionArgs, null, null, sortOrder);
}
default: {
throw new UnsupportedOperationException("Unknown uri: " + uri);
}
}
cursor.setNotificationUri(getContext().getContentResolver(), uri);
return cursor;
}
Please let me know if any additional information is required.
My Github repository is here
Please change these lines:
String selection = "MovieContract.Movie.FAVORITE = ?";
String [] selectionArgs = new String [] {"'1'"};
String sortOrder = "MovieContract.Movie.TITLE";
to
String selection = MovieContract.Movie.FAVORITE + " = ?";
String [] selectionArgs = new String [] {"1"};
String sortOrder = MovieContract.Movie.TITLE;
or to (will work as well)
String selection = "favorite = ?";
String [] selectionArgs = new String [] {"1"};
String sortOrder = "title";
Related
I'm working on an small android app that maintains a small database of tools which I lend out to other people.
As part of the app, I am incorporating an sqllite database, where I am having a bit of trouble performing queries and working with cursors once the queries have been executed.
The code in question is as follows:
String COLUMN_NAME = "toolName";
String[] columns = { COLUMN_NAME };
String selection = COLUMN_NAME + " =?";
String[] selectionArgs = {tool};
Cursor cursor = mToolDb.query(ToolStatisticContract.ToolStatisticEntry.TABLE_NAME, columns,
selection, selectionArgs, null, null, null, null);
return Integer.parseInt(cursor.getString(3));
The contract for the database is as follows:
public class ToolStatisticContract {
public static final class ToolStatisticEntry implements BaseColumns {
public static final String TABLE_NAME = "tooltable";
public static final String COLUMN_TOOL_NAME = "toolName";
public static final String COLUMN_LIFESPAN = "lifespan";
public static final String COLUMN_USAGE = "usageTime";
}
}
I am essentially trying to extract out the value from COLUMN_USAGE, which seems to be producing errors with regards to parsing the value to an integer. The value in the COLUMN is actually an integer typecasted as a String from a previous segment of code, so I'm fairly certain the error is encompasssed with the code snippets above.
Thanks again in advance for all your help!
The code in question is as follows
The net SQL statement is something like:
SELECT toolName FROM tooltable WHERE toolName = ?
And there is no column with index 3, since you are only returning 1 column.
You need to:
Have usageTime in your column list (COLUMNS)
Move the Cursor to a valid row (as it initially is positioned before the first row)
Pass getInteger() the value that lines up with COLUMNS to retrieve usageTime
You could use the following. This uses null instead of columns, which will get all columns (i.e. resolves to SELECT * FROM table). It checks that a row has been returned and only then does it try to get the data. It also closes the cursor (you should close a cursor when done with it). It uses cursor.getInt() to get the integer value rather than convert it from a string to int. It assumes that you'll only get 1 row (if no rows then 0 will be returned).
int returnvalue = 0;
String COLUMN_NAME = "toolName";
String[] columns = { COLUMN_NAME };
String selection = COLUMN_NAME + " =?";
String[] selectionArgs = {tool};
Cursor cursor = mToolDb.query(ToolStatisticContract.ToolStatisticEntry.TABLE_NAME, null,
selection, selectionArgs, null, null, null, null);
if (cursor.getCount() > 0) {
cursor.moveToFirst();
returnvalue = cursor.getInt(2);
//or returnvalue = Integer.parseInt(cursor.getString(2));
}
cursor.close();
return returnvalue;
Note! I haven't checked this just coded it from memory, so apologies for the odd mistake.
To do the above using specific columns then you could use:-
String COLUMN_NAME = "toolName";
String[] columns = { COLUMN_USAGE };
String selection = COLUMN_NAME + " =?";
String[] selectionArgs = {tool};
Cursor cursor = mToolDb.query(ToolStatisticContract.ToolStatisticEntry.TABLE_NAME, columns,
selection, selectionArgs, null, null, null, null);
In which case the column index would be 0 (that is the index is according to the column's in the cursor). However it might be better to use, the following which gets the column index according to the column's name:-
cursor.getInt(cursor.getColumnIndex(COLUMN_USAGE);
The easiest way to read a single value from the database is to use a helper function that allows you to avoid having to handle cursor objects:
String query = "SELECT usageTime FROM tooltable WHERE toolName = ?";
String[] selectionArgs = { tool };
long returnvalue = DatabaseUtils.longForQuery(mToolDb, query, selectionArgs);
I am using query function in the SQLiteDatabase class in android for fetching contents from the sqlite database. It works fine. But when I am trying to use date function of sqlite in my query as follows, it does not return any rows.
SQLiteDatabase mDb = mDbHelper.getWritableDatabase();
String [] selectionArgs = new String[] {"date('2016-02-10 00:00:00')"};
String selection = "date(column_name) = ?";
String limit = 4;
String[] ALL_COLUMNS = new String[] { "id", "column_name","column_name2"};
cursor = mDb.query("table_name", ALL_COLUMNS,selection , selectionArgs, "column_name" + " DESC", limit);
if (cursor != null) {
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
//code to read each row
}
cursor.close();
}
Can anyone tell me what is wrong with the above code?
Also, is there a way to compare the date (and not the time) from the sqlite database using SQLiteDatabase class query function?
In SQLite dates are strings. Reference: https://www.sqlite.org/lang_datefunc.html
Therefore, simply remove the date() function from the date value and from the column name:
i.e.: change this
String [] selectionArgs = new String[] {"date('2016-02-10 00:00:00')"};
String selection = "date(column_name) = ?";
to this
String [] selectionArgs = new String[] {"2016-02-10"};
String selection = "column_name = ?";
If you need the time, too:
String [] selectionArgs = new String[] {"2016-02-10 00:00:00"};
String selection = "column_name = ?";
See the SQLite supported datetime strings in the link above
I'm trying to retrieve a single row from my database using SQLite but for some reason my program crashes. When I search the log I get the next error:
Index -1 is requested with size of 1
I searched the web for solutions but it looks like my code is correct. I can delete a row with that parameter so I know that the position is right. It's probably how I write the query but I just don't know what's wrong with it. Can someone see why I'm doing wrong?
This is the code for the query:
public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + /jokes_table");
final Uri _URI = Uri.parse(MyContentProvider.CONTENT_URI + "/2");
String positions = intent.getStringExtra("position_in_db");
Cursor cur = getBaseContext().getContentResolver().query(_URI, new String[] {"Joke","Author","Date","Status"} , MyContentProvider.ID + " = " + intent.getStringExtra("position_in_db") , null , null );
my query method :
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
String a;
switch (sUriMatcher.match(uri))
{
case COLLECTION_URI_INDICATOR:
qb.setTables(TABLE_NAME);
qb.setProjectionMap(projectionMap);
break;
case SINGLE_ITEM_URI_INDICATOR:
qb.setTables(TABLE_NAME);
qb.setProjectionMap(projectionMap);
qb.appendWhere(ID);
break;
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
SQLiteDatabase db = mOpenHelper.getReadableDatabase();
Cursor c = qb.query(db, projection, selection, selectionArgs, null, null, null);
c.setNotificationUri(getContext().getContentResolver(), uri);
return c;
}
When I try to get all the rows by that query it works fine. The only problem is that I can't retrieve specific row. I try to change the selection with ? and try to see the string before I call the query but it won't work. Trying to reach data from the cursor by
cur.getString(getColumnIndex("Joke"));
ends the program. Can someone help me please?
What is your selection and selectionArgs??
you can try this
selection = ROW_ID_COLUMN_NAME + " =? "; // take a note on the "Space" between this statement
selectionArgs = { ROW_ID };
c = qb.query(db, projection, selection, selectionArgs, null, null, null);
// moveToFirst() method may prevent error when accessing 0 row cursor.
if (c.moveToFirst()) {
c.getString(getColumnIndex("Joke"));
}
i am trying to do a query of my database for a string lets call it "Test" and then find out what row that particular string is in and save that number to use. I thought i had this figured out before but now it is not working for some reason and i get an error saying no such column "Test".
here is my code
public String getRow(String value){
ContactDB db = new ContactDB(this);
db.open();
Cursor curs = db.getId(value);
String test = curs.getString(curs.getColumnIndex(db.NAME));
curs.close();
Log.v("Contact", "Row ID: " + test);
db.close();
return test;
}
"Test" is sent into that as value
this is in my database
//---retrieve contact id---
public Cursor getId(String where){
Cursor c = db.query(DATABASE_TABLE, new String[] {ID},where,null,null,null,null);
if (c != null)
c.moveToFirst();
return c;
}
i dont remember changing anything from when i first tested it so i dont know why it wont work now
There are 2 errors that i could notice:
In the query
Cursor c = db.query(DATABASE_TABLE, new String[] {ID},where,null,null,null,null);
only the ID column is selected whereas you are trying to fetch details for column NAME
String test = curs.getString(curs.getColumnIndex(db.NAME));
include the name column as well in the select clause : something like
Cursor c = db.query(DATABASE_TABLE, new String[] {ID,NAME},where,null,null,null,null);
In the where clause you need to write the condition string excluding "where"
in your case String where contains value "Test". Hence the filter condition should be as
String whereClasue = NAME + " = '" + where + "'";
The query should be something like this:
public Cursor getId(String where){
Cursor c = db.query(DATABASE_TABLE, new String[] {ID,PHONE_NUMBER,NAME},NAME + " = '" + where + "'",null,null,null,null);
if (c != null)
c.moveToFirst();
return c;
}
I am trying to use this query upon my Android database, but it does not return any data. Am I missing something?
SQLiteDatabase db = mDbHelper.getReadableDatabase();
String select = "Select _id, title, title_raw from search Where(title_raw like " + "'%Smith%'" +
")";
Cursor cursor = db.query(TABLE_NAME, FROM,
select, null, null, null, null);
startManagingCursor(cursor);
return cursor;
This will return you the required cursor
Cursor cursor = db.query(TABLE_NAME, new String[] {"_id", "title", "title_raw"},
"title_raw like " + "'%Smith%'", null, null, null, null);
Alternatively, db.rawQuery(sql, selectionArgs) exists.
Cursor c = db.rawQuery(select, null);
This will also work if the pattern you want to match is a variable.
dbh = new DbHelper(this);
SQLiteDatabase db = dbh.getWritableDatabase();
Cursor c = db.query(
"TableName",
new String[]{"ColumnName"},
"ColumnName LIKE ?",
new String[]{_data+"%"},
null,
null,
null
);
while(c.moveToNext()){
// your calculation goes here
}
I came here for a reminder of how to set up the query but the existing examples were hard to follow. Here is an example with more explanation.
SQLiteDatabase db = helper.getReadableDatabase();
String table = "table2";
String[] columns = {"column1", "column3"};
String selection = "column3 =?";
String[] selectionArgs = {"apple"};
String groupBy = null;
String having = null;
String orderBy = "column3 DESC";
String limit = "10";
Cursor cursor = db.query(table, columns, selection, selectionArgs, groupBy, having, orderBy, limit);
Parameters
table: the name of the table you want to query
columns: the column names that you want returned. Don't return data that you don't need.
selection: the row data that you want returned from the columns (This is the WHERE clause.)
selectionArgs: This is substituted for the ? in the selection String above.
groupBy and having: This groups duplicate data in a column with data having certain conditions. Any unneeded parameters can be set to null.
orderBy: sort the data
limit: limit the number of results to return
Try this, this works for my code
name is a String:
cursor = rdb.query(true, TABLE_PROFILE, new String[] { ID,
REMOTEID, FIRSTNAME, LASTNAME, EMAIL, GENDER, AGE, DOB,
ROLEID, NATIONALID, URL, IMAGEURL },
LASTNAME + " like ?", new String[]{ name+"%" }, null, null, null, null);