I've got an SQLite database in my Android app. I want to be able to select a random row based on the YEAR column in the database. I'm already able to select a random row from the entire table like so:
public String[] getTEST3RandChVerScrip() {
Cursor cursor = this.db.query("provtable Order BY RANDOM() LIMIT 1",
new String[] { KEY_MAKE, KEY_MODEL, KEY_NOTE }, null,
null, null, null, null);
if (cursor != null) {
for (cursor.moveToFirst(); !cursor.isAfterLast();) {
String colStrings[] = new String[3];
colStrings[0] = cursor.getString(0);
colStrings[1] = cursor.getString(1);
colStrings[2] = cursor.getString(2);
return colStrings;
}
}
return null;
}
But when I try and add a selection argument, the app errors out. Here's where I've added the selection argument:
public String[] getTEST3RandChVerScrip() {
Cursor cursor = this.db.query("provtable Order BY RANDOM() LIMIT 1",
new String[] { KEY_MAKE, KEY_MODEL, KEY_NOTE }, KEY_YEAR = "1964",
null, null, null, null);
if (cursor != null) {
for (cursor.moveToFirst(); !cursor.isAfterLast();) {
String colStrings[] = new String[3];
colStrings[0] = cursor.getString(0);
colStrings[1] = cursor.getString(1);
colStrings[2] = cursor.getString(2);
return colStrings;
}
}
return null;
}
Is the syntax incorrect in KEY_YEAR = "1964"? If so any idea what it should be?
As per tyczj's answer I've modified the query to:
Cursor cursor = this.db.query("provtable Order BY RANDOM() LIMIT 1",
new String[] { KEY_MAKE, KEY_MODEL, KEY_NOTE }, KEY_YEAR + "=?",
new String[] {"1964"}, null, null, null);
... and I'm still getting an error that says: 06-20 15:18:33.644: E/AndroidRuntime(4758): android.database.sqlite.SQLiteException: near "WHERE": syntax error: , while compiling: SELECT make, model, note FROM provtable Order BY RANDOM() LIMIT 1 WHERE year=?
You shouldn't put order by in the table name area
this.db.query("provtable",
new String[] { KEY_MAKE, KEY_MODEL, KEY_NOTE }, KEY_YEAR + "=?",
new String[] {"1964"}, null, null, "RANDOM() LIMIT 1");
it should be
KEY_YEAR+"=1964"
however better syntax wound be to put your selection as KEY_YEAR+"=?" and then you selectionArgs should be new String[] {"1964"}
also post the error
Related
The below code gives me single row using id:
public DataObject getContact(int id) {
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.query(TABLE_CONTACTS, new String[] { KEY_ID,
KEY_PHN, KEY_PTYPE, KEY_PDATE ,KEY_PNAME, KEY_PNOTE }, KEY_ID + "=?",
new String[] { String.valueOf(id) }, null, null, null, null);
if (cursor != null) cursor.moveToFirst();
DataObject contact = new DataObject(Integer.parseInt(cursor.getString(0)),cursor.getString(1),
cursor.getString(2), cursor.getString(3),cursor.getString(4),cursor.getString(5));
cursor.close();
return contact;
}
but I want is using a string,for eg: if my database is as below, then I want get the whole row, when I say name2 (that means it should return address2 and phno2)
name1 address1 phnno1
name2 address2 phnno2
name3 address3 phnno3
name4 address4 phnno4
I use your example to build my answer.
You can do :
Cursor cursorTable = db.query(CONTACTS,
new String[]{NAME, ADDRESS, PHNNO},
NAME + "= ?",
new String[]{"name2"},
null,
null,
null);
But if you want this to return only information for name2 you have to be sure there is only one row with "name2" as NAME
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);
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[]).
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) {
}
How would I filter the returned contacts by the groupName?
#Override
public void onItemSelected(AdapterView<?> parent, View view, int pos,
long id) {
String groupName = parent.getItemAtPosition(pos).toString();
Log.i(this.toString(), String.format("Show Group: %s", groupName));
Cursor cur = this.getContentResolver().query(
ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
if (cur.getCount() > 0) {
while (cur.moveToNext()) {
String name = cur
.getString(cur
.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
if (name != null) {
Log.i(this.toString(), String.format("Show: %s", name));
}
}
cur.close();
}
}
I was able to filter contacts by group by using the following query:
Cursor c = this.managedQuery(Data.CONTENT_URI, new String[] {
Contacts.DISPLAY_NAME, Contacts._ID },
GroupMembership.GROUP_ROW_ID + " = ?",
new String[] { groupId }, Phone.TIMES_CONTACTED + " DESC");
Obviously you need to know the Group Id in order to complete this, how I did this was used a SimpleCursorAdapter to a Spinner w/the following Cursor:
Cursor c = managedQuery(Groups.CONTENT_URI,
new String[] { Groups.SYSTEM_ID, Groups._ID,},
Groups.SYSTEM_ID + " NOT NULL",
null, null);
This works for me for getting all group IDs rather than just system IDs:
public HashMap<String, Long> fillGroupsHashMap(HashMap<String, Long> groups) //
{
Cursor tempCur = activity.managedQuery(Groups.CONTENT_URI,
new String[] { Groups._ID, Groups.TITLE }, null, null, null);
tempCur.moveToFirst();
while (tempCur.moveToNext()) //
{
groups.put(tempCur.getString(1), tempCur.getLong(0));
}
return groups;
}
Unfortunately only System Groups ("groups that have a special meaning to the sync adapter") have SYSTEM_IDs. So this method is not bullet proof.
I had a heachache with this, but finally i get this working with whis code, and now i can filter by only phone numbers and avoid repeated and unused groups:
String[] GROUP_PROJECTION = new String[] {
ContactsContract.Groups._ID, ContactsContract.Groups.TITLE,ContactsContract.Groups.SUMMARY_COUNT ,ContactsContract.Groups.SUMMARY_WITH_PHONES };
Cursor c = context.getApplicationContext().getContentResolver().query(
ContactsContract.Groups.CONTENT_SUMMARY_URI,
GROUP_PROJECTION,
ContactsContract.Groups.SUMMARY_WITH_PHONES +"> 0"
, null, ContactsContract.Groups.TITLE + " ASC");