SQLite rawQuery with multiple WHERE clauses - android

I have retrieved 2 values through the putExtra and getStringExtra method in another class. BOth these values are correct. I need to use these 2 values in my SQL query:
final Cursor cursor = sdb.rawQuery("SELECT match_player_name FROM match_response WHERE match_date=? AND " +
"match_response =?"+new String [] {String.valueOf(date),String.valueOf(response)}, null);
I am unfamiliar using rawQuery with more than 1 condition. Have I the correct syntax? I have a record in my SQLite database satisfying this condition.

This is an example:
Cursor cur = database.rawQuery("select name from Table where ID=? and SubCategoryID=?",
new String [] {String1,String2});

public Cursor getMachineServices(){
SQLiteDatabase db = this.getReadableDatabase();
Cursor c = db.rawQuery("select row1, from maquina where something = x AND somethingelse = y", new String[]{});
return c;
}
Then on your activity where you want to display it you must do:
Database db;
db = new Database(yourActivity);
Cursor c = db.getMachineServices);
if (c.moveToFirst()) {
do {
String machines
c.getString(c.getColumnIndex("row1"));
//you can use the variable machines where you want
} while (c.moveToNext());
}

Related

Android SqlLite check if two values exist in 2 different columns

I am developing an application where the user inputs title and the date. I want to prevent the duplicated titles being inputted on the same day in to database. I am checking if the title exists on the selected date. However my query seems not to work and i don't know why, the application just crashes.Is this query correct? Can someone help?
public boolean checkExist(String title, String date) {
SQLiteDatabase db = this.getWritableDatabase();
Cursor c = db.rawQuery("SELECT * FROM "+TABLE_NAME+" WHERE "+TITLE+"=?" +"AND" + DATE+"=?", new String[] {title,date});
boolean exists = c.moveToFirst();
c.close();
return exists;
}
One issue that you have is that c.moveToFirst will always fail if a match does not exist as you are trying to move to a row in an empty cursor.
The resolution is to not use c.moveToFirst and instead get the count of the rows and then set the return value accordingly.
e.g.
public boolean checkExist(String title, String date) {
SQLiteDatabase db = this.getWritableDatabase();
Cursor c = db.rawQuery("SELECT * FROM "+TABLE_NAME+" WHERE "+TITLE+"=?" +"AND" + DATE+"=?", new String[] {title,date});
boolean exists = c.getCount() > 0;
c.close();
return exists;
}
The second issue is that the query itself is wrong as you do not have spaces either side of the AND keyword. That is instead of
Cursor c = db.rawQuery("SELECT * FROM "+TABLE_NAME+" WHERE "+TITLE+"=?" +"AND" + DATE+"=?", new String[] {title,date});
You should have
Cursor c = db.rawQuery("SELECT * FROM "+TABLE_NAME+" WHERE "+TITLE+"=?" +" AND " + DATE+"=?", new String[] {title,date});
Personally, I setup constants for SQL keywords that include the space and then use these. So I'd have something along the lines of +TITLE+"=?" + SQLAND + DATE+"=?". Where SQLAND would be defined along the lines of String SQLAND=" AND ";
PS look at Cricket_007's answer, the code is neater/better it's easier to read.
Your spacing is off. TITLE+"=?" +"AND" + DATE becomes TITLE=?ANDDATE=?
I would suggest this. See DatabaseUtils.queryNumEntries
public boolean checkExist(String title, String date) {
SQLiteDatabase db = getReadableDatabase();
String[] args = new String[] {title,date};
String filter = String.format("%s=? AND %s=?", TITLE, DATE);
return DatabaseUtils.queryNumEntries(db, TABLE_NAME, filter, args) > 0;
}
you should be using c.getCount() instead of c.moveToFirst()
if the value is greater than 0, then it exists

Error retrieving cursor value as string

I have an SQLite-Database with four columns
ID
Name
symptoms
Medicine
My Helper class code
public Cursor getMedicine(String symptom1)
{
SQLiteDatabase db=helper.getReadableDatabase();
Cursor c = db.rawQuery("SELECT medicine FROM diseases WHERE symptoms = ?;",new String[] {symptom1});
c.moveToFirst();
return c;
}
And here is code of my activity class :
String med = "";
Disp_med_DBHelper medicalHelp = new Disp_med_DBHelper(this);
medicalHelp.open();
medicalHelp.getMedicine(Value1);
med = medicalHelp.getMedicine(Value1).toString();
t1.setText(med);
medicalHelp.close();
Where t1 is my textbox, and Value1 is the string that we need to send to database helper to query the database.
When I check output on my textbox, I get the following output
android.database.sqlire.SQLiteCursor#4174986
What should I do to get it fixed?
Method toString() returns string representation of object Cursor. You have to use method getString(int column) from Cursor class.
Something like this:
med = medicalHelp.getMedicine(Value1).getString(0);
More info: https://developer.android.com/reference/android/database/Cursor.html
use this method instead:
public String getMedicine(String symptom1) {
SQLiteDatabase db = helper.getWritableDatabase();
Cursor c = db.rawQuery("SELECT medicine FROM diseases WHERE symptoms = ?;", new String[]{symptom1});
if (c.moveToFirst()) {
return c.getString(c.getColumnIndex("medicine"));
}
return null;
}
and then in your activity:
med = medicalHelp.getMedicine(Value1)
if(med!=null){
t1.setText(med);
}
Even when the cursor contains only a single value, it still behaves as a cursor that might have multiple columns and multiple rows. So you have to go to the first row (with moveToFirst(), which might fail), and read the value from the first column (with getString(0)).
However, for this simple situation, there is a helper function that allows you to avoid having to muck around with a cursor:
public Cursor getMedicine(String symptom1) {
SQLiteDatabase db = helper.getReadableDatabase();
return DatabaseUtils.stringForQuery(db,
"SELECT medicine FROM diseases WHERE symptoms = ?;",
new String[]{ symptom1 });
}

select one cell from sql database

I'm trying a simple SQL Command wihtin my Android-App, to get the age of a selected Person:
public int getAge(){
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery("SELECT * FROM persons WHERE name =? " + MainActivity.selectedPerson.getText().toString(), null);
int age = cursor.getInt(3); // column with ages
cursor.close();
db.close();
return age;
}
But when I run my app, it crashes when I call the function getAge(). I get the following Error:
SQLiteException: no such column: Max: , while compiling: SELECT * FROM persons WHERE name = Max
I don't get it. There is the name "Max" in the table. What am I doing wrong? Thanks in advance.
Edit 2:
With this one:
Cursor cursor = db.rawQuery("SELECT name FROM persons WHERE name = '" + MainActivity.selectedPerson.getText().toString() + "'", null);
I get a different error:
08-27 19:43:47.573: E/AndroidRuntime(6161): android.database.CursorIndexOutOfBoundsException: Index -1 requested, with a size of 1
what does this mean?
You should consider using the selectionArgs parameter of rawQuery() to prevent SQL Injection Attacks:
Cursor cursor = db.rawQuery("SELECT * FROM persons WHERE name = ?", new String[] { MainActivity.selectedPerson.getText().toString() });
Also you only need one column so rather than wasting resources by selecting them all with *, you should just select the one column:
Cursor cursor = db.rawQuery("SELECT age FROM persons WHERE name = ?", new String[] { MainActivity.selectedPerson.getText().toString() });
Hope that helps!
All together it should look like:
public int getAge(){
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery("SELECT age FROM persons WHERE name = ?", new String[] { MainActivity.selectedPerson.getText().toString() });
int age;
// Check if you have a valid result and move to the first row to read it
if(cursor.moveToFirst())
age = cursor.getInt(0);
// Prevent a crash if there is no data for this name
else
age = 0;
cursor.close();
db.close();
return age;
}
Chan ge the 3rd line of your program:
Cursor cursor = db.rawQuery("SELECT * FROM persons WHERE name =? " + MainActivity.selectedPerson.getText().toString(), null);
to this:
Cursor cursor = db.rawQuery("SELECT * FROM persons WHERE name = ?", new String[] { MainActivity.selectedPerson.getText().toString()} );
Try this:
public int getAge(){
int age;
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery("SELECT * FROM persons WHERE name = '" + MainActivity.selectedPerson.getText().toString()+"'",null);
if(cursor.moveToFirst())
{
age = cursor.getInt(3); // column with ages
}
cursor.close();
db.close();
return age;
}
You missed the single quotes (' ') in your sql command. That's why MAX was taken as a column and not as a value.

Android and SQLite - retrieve max id of a table

I am trying to create a method to retrieve the max id of a specific table.
This is the code that doesn't work:
private long getMaxId()
{
String query = "SELECT MAX(id) AS max_id FROM mytable";
Cursor cursor = db.rawQuery(query, new String[] {"max_id"});
int id = 0;
if (cursor.moveToFirst())
{
do
{
id = cursor.getInt(0);
} while(cursor.moveToNext());
}
return id;
}
The exception being thrown is this:
E/AndroidRuntime(24624): android.database.sqlite.SQLiteException: bind or column index out of range: handle 0x200408
I suppose the problem is this line:
id = cursor.getInt(0);
Does anybody have an idea of how to fix this?
Thanks.
Try replacing:
Cursor cursor = db.rawQuery(query, new String[] {"max_id"});
with
Cursor cursor = db.rawQuery(query, null);
From the rawQuery description , for the 2nd argument:
You may include ?s in where clause in
the query, which will be replaced by
the values from selectionArgs. The
values will be bound as Strings.
Since you dont have any placeholders in your SQL query, maybe it is the source of the problem.

Get last inserted value from sqlite database Android

I am trying to get the last inserted rowid from a sqlite database in Android. I have read a lot of posts about it, but can't get one to work.
This is my method:
public Cursor getLastId() {
return mDb.query(DATABASE_TABLE, new String[] {KEY_WID}, KEY_WID + "=" + MAX(_id), null, null, null, null, null);}
I have tried with MAX, but I must be using it wrong. Is there another way?
Well actually the SQLiteDatabase class has its own insert method which returns the id of the newly created row. I think this is the best way to get the new ID.
You can check its documentation here.
I hope this helps.
Use
SELECT last_insert_rowid();
to get the last inserted rowid.
If you are using AUTOINCREMENT keyword then
SELECT * from SQLITE_SEQUENCE;
will tell you the values for every table.
To get the last row from the table..
Cursor cursor = theDatabase.query(DATABASE_TABLE, columns,null, null, null, null, null);
cursor.moveToLast();
Use moveToLast() in Cursor interface.
From android.googlesource.com
/**
* Move the cursor to the last row.
*
* <p>This method will return false if the cursor is empty.
*
* #return whether the move succeeded.
*/
boolean moveToLast();
Simple example:
final static String TABLE_NAME = "table_name";
String name;
int id;
//....
Cursor cursor = db.rawQuery("SELECT * FROM " + TABLE_NAME, null);
if(cursor.moveToLast()){
//name = cursor.getString(column_index);//to get other values
id = cursor.getInt(0);//to get id, 0 is the column index
}
Or you can get the last row when insertion(Which is #GorgiRankovski have mentioned):
long row = 0;//to get last row
//.....
SQLiteDatabase db= this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(COLUMN_NAME, name);
row = db.insert(TABLE_NAME, null, contentValues);
//insert() returns the row ID of the newly inserted row, or -1 if an error occurred
Also their is a multiple ways you can do this using query:
One is expressed by #DiegoTorresMilano
SELECT MAX(id) FROM table_name. or to get all columns values SELECT * FROM table_name WHERE id = (SELECT MAX(id) FROM table_name).
If your PRiMARY KEY have sat to AUTOINCREMENT, you can SELECT vaules occording to max to min and limit the rows to 1 using SELECT id FROM table ORDER BY column DESC LIMIT 1
(If you want each and every value, use * instead of id)
If you want the last_insert_id just afert a insert you can use that :
public long insert(String table, String[] fields, String[] vals )
{
String nullColumnHack = null;
ContentValues values = new ContentValues();
for (int i = 0; i < fields.length; i++)
{
values.put(fields[i], vals[i]);
}
return myDataBase.insert(table, nullColumnHack, values);
}
The insert method returns the id of row just inserted or -1 if there was an error during insertion.
long id = db.insert("your insertion statement");
db is an instance of your SQLiteDatabase.
Try this:
public Cursor getLastId() {
return mDb.query(DATABASE_TABLE, new String[] { **MAX(id)** }, null, null, null, null, null, null);}
/**
* #return
*/
public long getLastInsertId() {
long index = 0;
SQLiteDatabase sdb = getReadableDatabase();
Cursor cursor = sdb.query(
"sqlite_sequence",
new String[]{"seq"},
"name = ?",
new String[]{TABLENAME},
null,
null,
null,
null
);
if (cursor.moveToFirst()) {
index = cursor.getLong(cursor.getColumnIndex("seq"));
}
cursor.close();
return index;
}
I use this
public int lastId(){
SQLiteDatabase db =
this.getReadableDatabase();
Cursor res = db.rawQuery( "select * from resep", null );
res.moveToLast();
return res.getInt(0);
}
In your DbHelper class,
public long getLastIdFromMyTable()
{
SQLiteDatabase db = this.getReadableDatabase();
SQLiteStatement st = db.compileStatement("SELECT last_insert_rowid() from " + MY_TABLE);
return st.simpleQueryForLong();
}

Categories

Resources