how to GET the SINGLE ROW with cursor in android? - android

i want to get the row from databas which name = jiten
but is gives error in syntax can anyone tell me what is the right syntax for
getting the single row
here is my code for database class
public void getdata()
{
Cursor cursor = myDataBase.query("emp", new String[] {"email","name"}, " name='jiten'",new String[]{}, null, null, null);
Log.e("running", "cursor run");
if(cursor!=null)
{
Log.e("running", "curosr is not null");
while(cursor.moveToFirst())
{
Log.e("running", "curosr while loop enter");
String temp = (cursor.getString(cursor.getColumnIndex(email)));
String temp2 =(cursor.getString(cursor.getColumnIndex(name)));
Log.e("running", "id email" +temp+ " name"+temp2);
}
}
}

You are missing the selectionArgs
public Cursor query (String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit)
You may include ?s in selection, which will be replaced by the values
from selectionArgs, in order that they appear in the selection. The
values will be bound as Strings.
http://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html
in your case it would be:
Cursor cursor = myDataBase.query("emp", new String[] {"email","name"}, "name=?",new String[]{"jiten"}, null, null, null);

Related

How do implicit joined columns work with Android contacts data?

I'm querying the ContactsContract.Data table to find phone records.
I get an error when I create a new CursorLoader:
java.lang.IllegalArgumentException: Invalid column deleted
My code:
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.provider.ContactsContract.Data;
...
String[] projection = {
Phone.DELETED,
Phone.LOOKUP_KEY,
Phone.NUMBER,
Phone.TYPE,
Phone.LABEL,
Data.MIMETYPE,
Data.DISPLAY_NAME_PRIMARY
};
// "mimetype = ? AND deleted = ?"
String selection = Data.MIMETYPE + " = ? AND " Phone.DELETED + " = ?";
String[] args = {Phone.CONTENT_ITEM_TYPE, "0"};
return new CursorLoader(
this,
Data.CONTENT_URI,
projection,
selection,
args,
null);
Any idea why the Phone.DELETED column isn't included in the cursor? The documentation does say -
Some columns from the associated raw contact are also available
through an implicit join.
Looks like you've found a feature that has been documented in many places, but hadn't been implemented yet. I opened a bug for tracking this issue - lets see what AOSP guys have to say on the subject (bug report).
Meanwhile, you can use the following workaround:
Uri uri = ContactsContract.RawContactsEntity.CONTENT_URI;
String[] projection = {
Phone._ID,
Phone.DELETED,
//Phone.LOOKUP_KEY,
Phone.NUMBER,
Phone.TYPE,
Phone.LABEL,
Data.MIMETYPE,
Data.DISPLAY_NAME_PRIMARY
};
String selection = Data.MIMETYPE + " = ? AND " + Data.DELETED + " = ?";
String[] args = {
Phone.CONTENT_ITEM_TYPE, "0"
};
return new CursorLoader(
this,
uri,
projection,
selection,
args,
null);
Changes:
Use RawContactsEntity's URI
LOOKUP_KEY is not accessible via above URI - you'll have to execute additional query if you absolutely need this column
_ID column will be required if you are going to use the resulting Cursor in CursorAdapter.
Edit: following #MichaelAlanHuff's request I'm posting the parts of code which this answer is based upon
From com.android.providers.contacts.ContactsProvider2#queryLocal() (source code of ContactsProvider2):
protected Cursor queryLocal(final Uri uri, final String[] projection, String selection,
String[] selectionArgs, String sortOrder, final long directoryId,
final CancellationSignal cancellationSignal) {
final SQLiteDatabase db = mDbHelper.get().getReadableDatabase();
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
String groupBy = null;
String having = null;
String limit = getLimit(uri);
boolean snippetDeferred = false;
// The expression used in bundleLetterCountExtras() to get count.
String addressBookIndexerCountExpression = null;
final int match = sUriMatcher.match(uri);
switch (match) {
...
case DATA:
case PROFILE_DATA:
{
final String usageType = uri.getQueryParameter(DataUsageFeedback.USAGE_TYPE);
final int typeInt = getDataUsageFeedbackType(usageType, USAGE_TYPE_ALL);
setTablesAndProjectionMapForData(qb, uri, projection, false, typeInt);
if (uri.getBooleanQueryParameter(Data.VISIBLE_CONTACTS_ONLY, false)) {
qb.appendWhere(" AND " + Data.CONTACT_ID + " in " + Tables.DEFAULT_DIRECTORY);
}
break;
}
...
}
qb.setStrict(true);
// Auto-rewrite SORT_KEY_{PRIMARY, ALTERNATIVE} sort orders.
String localizedSortOrder = getLocalizedSortOrder(sortOrder);
Cursor cursor = query(db, qb, projection, selection, selectionArgs, localizedSortOrder, groupBy,
having, limit, cancellationSignal);
if (readBooleanQueryParameter(uri, Contacts.EXTRA_ADDRESS_BOOK_INDEX, false)) {
bundleFastScrollingIndexExtras(cursor, uri, db, qb, selection,
selectionArgs, sortOrder, addressBookIndexerCountExpression,
cancellationSignal);
}
if (snippetDeferred) {
cursor = addDeferredSnippetingExtra(cursor);
}
return cursor;
}
As you can see, there are two additional methods where SQLiteQueryBuilder used to build the query could be changed: setTablesAndProjectionMapForData() and additional query() method.
Source of com.android.providers.contacts.ContactsProvider2#setTablesAndProjectionMapForData():
private void setTablesAndProjectionMapForData(SQLiteQueryBuilder qb, Uri uri,
String[] projection, boolean distinct, boolean addSipLookupColumns, Integer usageType) {
StringBuilder sb = new StringBuilder();
sb.append(Views.DATA);
sb.append(" data");
appendContactPresenceJoin(sb, projection, RawContacts.CONTACT_ID);
appendContactStatusUpdateJoin(sb, projection, ContactsColumns.LAST_STATUS_UPDATE_ID);
appendDataPresenceJoin(sb, projection, DataColumns.CONCRETE_ID);
appendDataStatusUpdateJoin(sb, projection, DataColumns.CONCRETE_ID);
appendDataUsageStatJoin(
sb, usageType == null ? USAGE_TYPE_ALL : usageType, DataColumns.CONCRETE_ID);
qb.setTables(sb.toString());
boolean useDistinct = distinct || !ContactsDatabaseHelper.isInProjection(
projection, DISTINCT_DATA_PROHIBITING_COLUMNS);
qb.setDistinct(useDistinct);
final ProjectionMap projectionMap;
if (addSipLookupColumns) {
projectionMap =
useDistinct ? sDistinctDataSipLookupProjectionMap : sDataSipLookupProjectionMap;
} else {
projectionMap = useDistinct ? sDistinctDataProjectionMap : sDataProjectionMap;
}
qb.setProjectionMap(projectionMap);
appendAccountIdFromParameter(qb, uri);
}
Here you see the construction of table argument of the final query using StringBuilder which is being passed to several append*() methods. I'm not going to post their source code, but they really join the tables that appear in methods' names. If rawContacts table would be joined in, I'd expect to see a call to something like appendRawContactJoin() here...
For completeness: the other query() method that I mentioned does not modify table argument:
private Cursor query(final SQLiteDatabase db, SQLiteQueryBuilder qb, String[] projection,
String selection, String[] selectionArgs, String sortOrder, String groupBy,
String having, String limit, CancellationSignal cancellationSignal) {
if (projection != null && projection.length == 1
&& BaseColumns._COUNT.equals(projection[0])) {
qb.setProjectionMap(sCountProjectionMap);
}
final Cursor c = qb.query(db, projection, selection, selectionArgs, groupBy, having,
sortOrder, limit, cancellationSignal);
if (c != null) {
c.setNotificationUri(getContext().getContentResolver(), ContactsContract.AUTHORITY_URI);
}
return c;
}
The inspection of the above chain of methods led me to the conclusion that there is an officially documented feature which is not implemented.

how to use where clause in cursor query in sqlite

I want only particular rows that has "E" inside the column "TX_IDT". I used the following code but apps stops. In logcat the error says it is at db.query line.
public Cursor getAllRows( ) {
String where = null;
SQLiteDatabase db = helper.getReadableDatabase();
String[] columns = { VivzHelper.UID, helper.UID,helper.NAME,helper.TX_IDT};
String whereClause = "TX_IDT = ? ";
String[] whereArgs = new String[] { "E" };
Cursor c = db.query( VivzHelper.TABLE_NAME, columns,whereClause,whereArgs, null, null, NAME + " ASC"); // for out btn
if (c != null) {
c.moveToFirst();
}
return c;
}
`
Seems like you want record's containing "E" ,
Try this
Cursor c = db.query(VivzHelper.TABLE_NAME, columns, helper.TX_IDT +" LIKE '%E%' ", null, null, null, null);

SQLite in Android: when I pass any name that contains a quote, it throws and error

Adapter.java
public String getID(String i) throws SQLException
{
db=DBHelper.getReadableDatabase();
String ij="No Track Found";
Cursor mCursor =
db.query(true, TABLE, new String[] {KEY_ID}, KEY_NAME + "=" + "'"+i+"'", null,
null, null, null, null);
if (mCursor != null) {
mCursor.moveToFirst();
}
if (mCursor.moveToFirst())
{
ij=mCursor.getString(0);
}
return ij ;
}
The Question is when I pass any song's name that contain "'"(e.g. alexander's blade) , it throws and error. Otherwise all fine.
You should use the selectionArgs parameter:
db.query(true, //distinct
TABLE, //table
new String[] {KEY_ID}, //columns
KEY_NAME + "=?", //selection
new String[] {i}, //selectionArgs
null, //groupBy
null, //having
null, //orderBy
null //limit
);
Using selectionArgs also help to prevent SQL Injection
You need to call your method like this:
Cursor c = bd.query(Constantes.TABELA_APLICATIVO, COLS, "urlandroid = ?", new String[]{url}, null, null, null);
The caracter "?" represents the values on Third parameter(String[]).

Android: SQLite query with selection WHERE clause is not processed

I am trying to limit the database result by defining a SQL WHERE clause in the selection string of the query of the ContentResolver.
Cursor cursor = getContentResolver().query(uri, null, getSelectionString(), null, null);
...
public String getSelectionString() {
// TODO Replace latitude and longitude with database reference.
StringBuilder string = new StringBuilder();
string.append("latitude >= ").append(northEast.getLatitudeE6() / 1e6);
string.append(" AND ");
string.append("latitude <= ").append(southWest.getLatitudeE6() / 1e6);
string.append(" AND ");
string.append("longitude >= ").append(southWest.getLongitudeE6() / 1e6);
string.append(" AND ");
string.append("longitude <= ").append(northEast.getLongitudeE6() / 1e6);
return string.toString();
}
The database columns are defined as follows ...
public class CustomDatabase {
public static final class Contract {
public static final String COLUMN_NAME = "name";
public static final String COLUMN_LATITUDE = "latitude";
public static final String COLUMN_LONGITUDE = "longitude";
}
}
...
I am not particularly sure that I can inspect the query sent in cursor. If so, it does not contain the WHERE clause I sent:
SQLiteQuery: SELECT * FROM custom_db ORDER BY number ASC
Here is an example of the selection string:
latitude >= 48.203927 AND latitude <= 48.213851 AND longitude >= 16.36735 AND longitude <= 16.377648
Questions:
Is the WHERE clause syntactically correct?
Do I need apostrophs?
Am I forced to use both parameters (selection, selectionArgs) at a time in a query?
Where can I debug the whole query?
EDIT:
Here is the query() method of the ContentProvider ...
public class CustomProvider extends ContentProvider {
#Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
switch (URI_MATCHER.match(uri)) {
case URI_CODE_LOCATIONS:
return mCustomDatabase.getLocations();
}
return null;
}
... obviously, as biegleux guessed, I forgot to pass the parameters. Doh!
Here is the current implementation of the database method ...
public class CustomSQLiteOpenHelper extends SQLiteOpenHelper {
public Cursor getLocation() {
return mDatabaseHelper.getReadableDatabase().query(
CustomSQLiteOpenHelper.TABLE_NAME,
null, null, null, null, null, null);
}
Do you suggest that I change the method signature to the following to pass all parameters? Am I not exposing to much of the database interface this way?
public Cursor getLocations(String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy) {
return mDatabaseHelper.getReadableDatabase().query(
CustomSQLiteOpenHelper.TABLE_NAME,
columns, selection, selectionArgs, groupBy, having, orderBy);
}
Ok, so it seems query() method of your provider is causing problems.
Make sure it looks like following.
#Override
public abstract Cursor query (Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
...
// run the query
db.query(db, projection, selection, selectionArgs, groupBy, having, sortOrder, limit);
You are not forced to use selectionArgs parameter, but with it code is more readable.
To debug a query you can use
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
Log.e(TAG, qb.buildQuery(projection, selection, selectionArgs, groupBy, having, sortOrder, limit);
EDIT:
If you have a ContentProvider implemented you don't need to expose getLocations() method as you/users can use ContentProvider's query() method.
You should pass at least those arguments whose can be passed in query() method and those are projection, selection, selectionArgs and sortOrder.
Shouldn't that line be:
Cursor cursor = getContentResolver().query(uri, null, getSelectionString(), null, null);
Note the added parens after getSelectionString to indicate it's a method call, not a string (although I do wonder why that wouldn't throw an error as getSelectionString wouldn't exist as a string if my theory is correct...).

How do I order my SQLITE database in descending order, for an android app?

What is the most efficient method of showing my data in descending order?
public String getRank() {
String[] rank = new String[]{ KEY_ROWID };
Cursor c = scoreDb.query(DATABASE_TABLE, rank, null, null, null, null, null); //reading information from db.
String rankResult = "";
int iRow = c.getColumnIndex(KEY_ROWID); //Cursor looking for column setting equal to these ints.
for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext()) {
//Move to first row - where cursor starts and moves to next row as long it is not after last row.
rankResult = rankResult + c.getString(iRow) + "\n";
//Returning value of row that it is currently on.
}
return rankResult; //returning result
}
public String getName() {
String[] name = new String[]{ KEY_NAME };
Cursor c = scoreDb.query(DATABASE_TABLE, name, null, null, null, null, null); //reading information from db.
String nameResult = "";
int iRow1 = c.getColumnIndex(KEY_NAME); //Cursor looking for column setting equal to these ints.
for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext()) {
//Move to first row - where cursor starts and moves to next row as long it is not after last row.
nameResult = nameResult + c.getString(iRow1) + "\n";
//Returning value of row that it is currently on.
}
return nameResult; //returning result
}
public String getScore() {
String[] score = new String[]{ KEY_SCORE };
Cursor c = scoreDb.query(DATABASE_TABLE, score, null, null, null,null, null); //reading information from db.
String scoreResult = "";
int iRow2 = c.getColumnIndex(KEY_SCORE); //Cursor looking for column setting equal to these ints.
for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext()) {
//Move to first row - where cursor starts and moves to next row as long it is not after last row.
scoreResult = scoreResult + c.getString(iRow2) + "\n";
//Returning value of row that it is currently on.
}
return scoreResult; //returning result
}
Query has two syntax, the syntax you are using, last column represents orderBy, you just need to specify on what column you want to do orderBy +"ASC" (or) orderBy +"DESC"
Cursor c = scoreDb.query(DATABASE_TABLE, rank, null, null, null, null, yourColumn+" DESC");
Refer this documentation to understand more about query() method.
return database.rawQuery("SELECT * FROM " + DbHandler.TABLE_ORDER_DETAIL +
" ORDER BY "+DbHandler.KEY_ORDER_CREATED_AT + " DESC"
, new String[] {});
Cursor c = scoreDb.query(Table_Name, score, null, null, null, null, Column+" DESC");
Try this
According to docs:
public Cursor query (String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit);
and your ORDER BY param means:
How to order the rows, formatted as an SQL ORDER BY clause
(excluding the ORDER BY itself). Passing null will use the default
sort order, which may be unordered.
So, your query will be:
Cursor cursor = db.query(TABLE_NAME, null, null,
null, null, null, KEY_ITEM + " DESC", null);
public List getExpensesList(){
SQLiteDatabase db = this.getWritableDatabase();
List<String> expenses_list = new ArrayList<String>();
String selectQuery = "SELECT * FROM " + TABLE_NAME ;
Cursor cursor = db.rawQuery(selectQuery, null);
try{
if (cursor.moveToLast()) {
do{
String info = cursor.getString(cursor.getColumnIndex(KEY_DESCRIPTION));
expenses_list.add(info);
}while (cursor.moveToPrevious());
}
}finally{
cursor.close();
}
return expenses_list;
}
This is my way of reading the record from database for list view in descending order. Move the cursor to last and move to previous record after each record is fetched. Hope this helps~
Cursor c = myDB.rawQuery("SELECT distinct p_name,p_price FROM products order by Id desc",new String[]{});
this works for me!!!
you can do it with this
Cursor cursor = database.query(
TABLE_NAME,
YOUR_COLUMNS, null, null, null, null, COLUMN_INTEREST+" DESC");
SQLite ORDER BY clause is used to sort the data in an ascending or descending order, based on one or more columns.
Cursor c = scoreDb.query(DATABASE_TABLE, rank, null, null, null, null, yourColumn+" DESC");
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.query(
TABLE_NAME,
rank,
null,
null,
null,
null,
COLUMN + " DESC",
null);
We have one more option to do order by
public Cursor getlistbyrank(String rank) {
try {
//This can be used
return db.`query("tablename", null, null, null, null, null, rank +"DESC",null );
OR
return db.rawQuery("SELECT * FROM table order by rank", null);
} catch (SQLException sqle) {
Log.e("Exception on query:-", "" + sqle.getMessage());
return null;
}
}
You can use this two method for order
This a terrible thing! It costs my a few hours!
this is my table rows :
private String USER_ID = "user_id";
private String REMEMBER_UN = "remember_un";
private String REMEMBER_PWD = "remember_pwd";
private String HEAD_URL = "head_url";
private String USER_NAME = "user_name";
private String USER_PPU = "user_ppu";
private String CURRENT_TIME = "current_time";
Cursor c = db.rawQuery("SELECT * FROM " + TABLE +" ORDER BY " + CURRENT_TIME + " DESC",null);
Every time when I update the table , I will update the CURRENT_TIME for sort.
But I found that it is not work.The result is not sorted what I want.
Finally, I found that, the column "current_time" is the default row of sqlite.
The solution is, rename the column "cur_time" instead of "current_time".
About efficient method. You can use CursorLoader. For example I included my action. And you must implement ContentProvider for your data base. https://developer.android.com/reference/android/content/ContentProvider.html
If you implement this, you will call you data base very efficient.
public class LoadEntitiesActionImp implements LoaderManager.LoaderCallbacks<Cursor> {
public interface OnLoadEntities {
void onSuccessLoadEntities(List<Entities> entitiesList);
}
private OnLoadEntities onLoadEntities;
private final Context context;
private final LoaderManager loaderManager;
public LoadEntitiesActionImp(Context context, LoaderManager loaderManager) {
this.context = context;
this.loaderManager = loaderManager;
}
public void setCallback(OnLoadEntities onLoadEntities) {
this.onLoadEntities = onLoadEntities;
}
public void loadEntities() {
loaderManager.initLoader(LOADER_ID, null, this);
}
#Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
return new CursorLoader(context, YOUR_URI, null, YOUR_SELECTION, YOUR_ARGUMENTS_FOR_SELECTION, YOUR_SORT_ORDER);
}
#Override
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
}
#Override
public void onLoaderReset(Loader<Cursor> loader) {
}

Categories

Resources