I'm trying to use rawQuery to return a cursor with a few different rows of data to be passed into it. When there is only 1 argument it works. When there is more than 1 argument it displays the empty ListView state. I believe the issue lies here:
// Query for items from the database and get a cursor back. Edited code for clarity:
recipeCursor = db.rawQuery("SELECT course, name, _id " +
" FROM recipes WHERE _id = ?",
selectedRecipesSQL);
When the code works the selectedRecipesSQL would look something like:
String[] selectedRecipesSQL;
selectedRecipesSQL = new String[]{"2"};
And when it doesn't work it would be something like
String[] selectedRecipesSQL;
selectedRecipesSQL = new String[]{"2 OR 5"};
So, to be clear, I can display a single row of the table in my ListView, but if I try to display more than one row of the table then it won't display anything.
One ugly solution which has crossed my mind (but I haven't pursued) is that I need to edit the rawQuery selection statement to read something like:
recipeCursor = db.rawQuery("SELECT course, name, _id " +
" FROM recipes WHERE _id = ? OR _id = ? OR _id = ?",
selectedRecipesSQL);
I'd probably use a for loop to generate the correct amount of WHERE "_id = ?" and then use a string array:
selectedRecipesSQL = new String[]{"2", "5"};
One way of doing it is by passing the possible values of _id as 1 string which is a comma separated list like this:
selectedRecipesSQL = new String[]{"1,2,3"};
and in your query use the operator LIKE:
recipeCursor = db.rawQuery(
"SELECT course, name, _id FROM recipes WHERE ',' || ? || ',' LIKE '%,' || _id || ',%'",
selectedRecipesSQL
);
This works also for just 1 value.
static String multiply__concat_string(String text,String joiner_,int multiple_)
{
String output="";
for(int i=0;i<multiple_;i++)
{
output+=(text+joiner_);
}
if(output.length()>0)
{
output=output.substring(0,output.length()-1);
}
return output;
}
Use it like this :
selectedRecipesSQL = new String[]{"2", "5"};
db.rawQuery("SELECT course, name, _id " +
" FROM recipes WHERE _id IN("+multiply_concat_string("?",",",selectedRecipesSQL.length)+")",
selectedRecipesSQL);
Related
I want to update the a specific row of the Column.I tried to use the statement to set my value using 'db.update()'.But I cant.Is there any method which I can use to use the statement of the title to set the value of a specific row of a column?
Although the documentation explicitly mentions that the recommended and proper way to update a table is the method update(), your requirement can only be done with execSQL().
Either with execSQL(String sql):
db.execSQL("UPDATE Products SET Price = Price + 50 WHERE ProductID = 1");
or with execSQL (String sql, Object[] bindArgs):
db.execSQL(
"UPDATE Products SET Price = Price + ? WHERE ProductID = ?",
new String[] {"50", "1"}
);
This may help you. db.update() with ContentValues () is more safe updating method. Check this one.
int i = 50;
Cursor res = db.rawQuery("select * from Products where ProductId = 1 LIMIT 1");
if(res.getCount() > 0){
i += Integer.parseInt(res.getString(res.getColumnIndex("Price")));
}
ContentValues values = new ContentValues();
values.put("Price", i.toString());
db.update("Products",values,"ProductId = ?",new String[]{"1"});
I am not sure but I think that the problem may be setting Price column type as text. If so, change it integer.
To update your sql db use db.update(TABLE_NAME, values, where, whereArgs); You can read about here.The use case can look like this:
ContentValues cv = new ContentValues();
cv.put("column_name", "updated value");
db.update("table_name", cv, "column_id" + "=?",new String[]{"primary_id"});
update() only works with ContentValues which is a wrapper for SQL variable binding. You can only bind values, not expressions like Price + 50.
To use an expression like that, use execSQL() with the raw SQL string you already have.
You can also try
db.execSQL( "UPDATE Products SET Price = ? WHERE ProductID = ?", new String[] {Price+50 , "1"} );
In the app I am building, I need to access an SQLite database run a query in which I have a name in the "where" clause. This name is randomly generated (from another query) and is assigned to a global variable. This variable then get's passed to another query (in another method) where it's used. Something a little like this:
public class DatabaseAccess {
public static String player_name;
Cursor c = null;
public String getPlayerName(String string) {
c = db.rawQuery("select player_name FROM name_table where level = 1 ORDER BY RANDOM() LIMIT 1", new String[]{});
StringBuffer buffer = new StringBuffer();
while (c.moveToNext()) {
String diff = c.getString(0);
buffer.append("" + diff);
}
player_name = buffer.toString();
return buffer.toString();
}
public String getClue(String string) {
c = db.rawQuery("SELECT clue FROM clue_table where player_name = '" + player_name +"'", new String[]{});
StringBuffer buffer = new StringBuffer();
while (c.moveToNext()) {
String diff = c.getString(0);
buffer.append("" + diff);
}
return buffer.toString();
}
The issue is that some of the names in the database have a ' symbol in them (for example Dara O'Briain).
When a name like this comes up, my code crashes with the error message:
Caused by: android.database.sqlite.SQLiteException: near "Briain": syntax error (code 1): , while compiling: select alt_name FROM player_names where player_name = 'Dara O'Briain'
It looks like it see's the ' as a means to end the string and this causes a faulty query.
How can I account for these instances in my code?
c = db.rawQuery("SELECT clue FROM clue_table where player_name = '" +
player_name +"'", new String[]{});
// see here ^^^^^^^^^^^^^^
Ok, so that empty String[] array you're passing to the call is exactly the place parameters are supposed to go. So, the query should look like that:
c = db.rawQuery("SELECT clue FROM clue_table where player_name = ?", new String[]{player_name});
Just put a question mark where you want the parameter inserted. They will be inserted in order, the array can have more of these.
The driver will take care of escaping any apostrophes for you. If you don't escape user input in any way, you risk a lot. Consider player name coming from user input in the app, and they write into the search box on a whim:
' delete from users; --
If you just paste it into your query it now looks like this:
SELECT clue FROM clue_table where player_name = ''; delete from users; --'
And you get your data dropped as a free bonus to search function.
I'm searching for a word (variable) that occurs in multiple columns of a table. The search has to return the name of the columns in which the word in found.
I could use a foreach loop to go through each column seperately and know the presence of the word in that particular column when the returned cursor isn't null.
The problem is on how to use two different variables (one for column name and one for the word) in SQL query or rawQuery.
My code is as follows:
String[] columnsList = {"col1","col2","col3"};
String[] wordsList = {"fireman","camper","builder"};
for(String i : wordsList){
for(String j : columnsList){
Cursor wordQuery = myDatabaseHandle.rawQuery("Select * from myTableOne WHERE " + j + " = ?",new String[]{i});
if(!(wordQuery==null)){
Toast.makeText(this,j+"is success",Toast.LENGTH_SHORT).show();
}
}
}
But i'm unable to get the answer. I used a seperate string as:
String queryString = "Select * from myTableOne WHERE " + j ;
and in the query,
Cursor WordQuery = myDatabaseHandle.rawQuery(queryString+" = ?",new String[]{i});
But, it's just toasting the names of all columns.
Your error is here:
if(!(wordQuery==null)){
The cursor is never null.
It can contain 0 records, though.
You can check its length by using wordQuery.getCount()
Something like:
if((wordQuery.getCount() > 0)){
I have taken String value from a EditText and set it inside SELECT QUERY after WHERE condition
As
TextView tv = (TextView) findViewById(R.id.textView3);
EditTextet2 et = (EditText) findViewById(R.id.editText1);
String name = et.getText().toString();
Cursor c = db.rawQuery("SELECT * FROM tbl1 WHERE name = '"+name+"'", null);
c.moveToNext();
tv.setText(c.getString(c.getColumnIndex("email")));
But it doesn't work. Any suggestions?
Try trimming the string to make sure there is no extra white space:
Cursor c = db.rawQuery("SELECT * FROM tbl1 WHERE TRIM(name) = '"+name.trim()+"'", null);
Also use c.moveToFirst() like #thinksteep mentioned.
This is a complete code for select statements.
SQLiteDatabase db = this.getReadableDatabase();
Cursor c = db.rawQuery("SELECT column1,column2,column3 FROM table ", null);
if (c.moveToFirst()){
do {
// Passing values
String column1 = c.getString(0);
String column2 = c.getString(1);
String column3 = c.getString(2);
// Do something Here with values
} while(c.moveToNext());
}
c.close();
db.close();
Try using the following statement:
Cursor c = db.rawQuery("SELECT * FROM tbl1 WHERE name = ?", new String[] {name});
Android requires that WHERE clauses compare to a ?, and you then specify an equal number of ? in the second parameter of the query (where you currently have null).
And as Nambari mentioned, you should use c.moveToFirst() rather than c.moveToNext()
Also, could there be quotations in name? That could screw things up as well.
Here is the below code.
String areaTyp = "SELECT " +AREA_TYPE + " FROM "
+ AREA_TYPE_TABLE + " where `" + TYPE + "`="
+ id;
where id is the condition on which result will be displayed.
public User searchUser(String name) {
User u = new User();
SQLiteDatabase db = this.getWritableDatabase(); //get the database that was created in this instance
Cursor c = db.rawQuery("select * from " + TABLE_NAME_User+" where username =?", new String[]{name});
if (c.moveToLast()) {
u.setUsername(c.getString(1));
u.setEmail(c.getString(1));
u.setImgUrl(c.getString(2));
u.setScoreEng(c.getString(3));
u.setScoreFr(c.getString(4));
u.setScoreSpan(c.getString(5));
u.setScoreGer(c.getString(6));
u.setLevelFr(c.getString(7));
u.setLevelEng(c.getString(8));
u.setLevelSpan(c.getString(9));
u.setLevelGer(c.getString(10));
return u;
}else {
Log.e("error not found", "user can't be found or database empty");
return u;
}
}
this is my code to select one user and one only
so you initiate an empty object of your class then
you call your writable Database
use a cursor in case there many and you need one
here you have a choice Use : 1-
if (c.moveToLast()) { } //it return the last element in that cursor
or Use : 2-
if(c.moveToFirst()) { } //return the first object in the cursor
and don't forget in case the database is empty you'll have to deal with that in my case i just return an empty object
Good Luck
Detailed answer:
String[] selectionArgs = new String[]{name};
Cursor c = db.rawQuery(
"SELECT * FROM " + tabl1 +
" WHERE " + name + " = ? ", selectionArgs
);
selectionArgs : this takes the 'name' you desire to compare with, as argrument.
Here note "A Cursor object, which is positioned before the first entry of the table you refer to".
So,to move to first entry :
c.moveToFirst();
getColumnIndex(String ColumnName) : this returns the zero-based column index for the given column name.
tv.setText(c.getString(c.getColumnIndex("email")));
In case, you want to go searching through multiple rows for a given name under 'name' column then use loop as below:
if (cursor.moveToFirst()){
do{
////go traversing through loops
}while(cursor.moveToNext());
}
This should solve the problem.
I would like to get values from the database in this format
1 Audi
3 Nissan
But I am getting like this as of now. I don't need to get to include the _id in the output.But I couldn't eliminate as it throws a NullPointerException when I remove it.
id MAKE
=========
1 Audi
2 Audi
3 Nissan
4 Audi
this is my query I have used in
cursor = db.rawQuery(
"SELECT DISTINCT _id,MAKE FROM "+SQLiteAdapter.MYDATABASE_TABLE+
" WHERE MAKE || ' ' || MODEL LIKE ?", new String[]{"%" + "" + "%"}
);
Do have I to change the sequence entirely to get the output or make changes on the above code.Thanks.
my code
cursor = db.rawQuery("SELECT DISTINCT SERIES FROM "+SQLiteAdapter.MYDATABASE_TABLE+" WHERE YEAR=2012 AND MAKE='Audi' AND MODEL=?", new String[]{"A6"});
adapter = new SimpleCursorAdapter(this, R.layout.employee_list_item, cursor, new String[] {"series"}, new int[] {R.id.firstName});
employeeList.setAdapter(adapter);
try:
select min(id), min(make) from cars group by make
you can use SQLiteQueryBuilder's buildQueryString method:
buildQueryString (boolean distinct, String tables, String[] columns, String where, String groupBy, String having, String orderBy, String limit)