Querying sql database with if conditions - java

This might be stupid question but this code is not working..
String sql= "SELECT field, question, choice1, choice2, choice3, choice4, answer "
+ "FROM WineQuiz ORDER BY RANDOM() LIMIT 5";
Intent i = getIntent();
String mField1 = i.getStringExtra("FIELD1");
String mField2 = i.getStringExtra("FIELD2");
String mField3 = i.getStringExtra("FIELD3");
if(mField1!="" || mField2!="" || mField3!=""){
sql = "SELECT field, question, choice1, choice2, choice3, choice4, answer "
+ "FROM WineQuiz WHERE field='"+mField1+"' or field='"+mField2+"' or field='"+mField3+"' ORDER BY RANDOM() LIMIT 5";
Cursor c =db.rawQuery(sql, null);
What I'm trying to do is simple. I'm creating quiz app, which has SelectActivity sending string data of quiz field into this class receiving it with variables of mField1,2,3.
If SelectActivity does not send any string, the first sql(variable) is put into the query.
If one of the field is chosen, mField1 or 2 or 3 receives string data, then the second sql is put into the query.
However, the first sql querying does not work while the second one works well.
When I use the first sql query independently, it works pretty well. Thus, the first and second sql seems unable to exist at the same time though those two query has no problem by themselves.
Why is that??
Replying the comments, "Not work" means cursor has no data. My continuing code is below, and the error log "Cursor has no data" shows up. It literally means those array does not store any data.
Cursor c =db.rawQuery(sql, null);
if (c.getCount() > 0) { // If cursor has at least one row
c.moveToFirst();
do { // always prefer do while loop while you deal with database
cPos = c.getPosition();
array[cPos][0] = c.getString(c.getColumnIndex("field"));
array[cPos][1] = c.getString(c.getColumnIndex("question"));
array[cPos][2] = c.getString(c.getColumnIndex("choice1"));
array[cPos][3] = c.getString(c.getColumnIndex("choice2"));
array[cPos][4] = c.getString(c.getColumnIndex("choice3"));
array[cPos][5] = c.getString(c.getColumnIndex("choice4"));
array[cPos][6] = c.getString(c.getColumnIndex("answer"));
c.moveToNext();
//Retrieves whether the cursor is after the last row in this SQLServerResultSet object.
} while (!c.isAfterLast());
} else {
Log.e("SQL Query Error", "Cursor has no data");
}

Related

How can I account for the " ' " symbol (assigned to a name in a variable) as it causes my SQLite query to fail

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.

How to get number of particular name in sqlite table by query

I have a table in which name and number of people are stored. Now I want to make a method in sqlite helper class which will return the number of particular person whose name I will pass in the method
There is something wrong with my code.
Here is my code
public String fetchGroup(SQLiteDatabase inDatabase, String valueCheck){
String query = "SELECT * FROM groups WHERE groupname='" + valueCheck;
Cursor cursor = inDatabase.rawQuery(query,null);
String place = cursor.getString(cursor.getColumnIndex("contactid"));
return place;
Take care to use cursor.moveToFirst() command before reading datas
Else, instead counting the number of people in Java, you can just modify your query to have only this number return.
Something like this :
public String fetchGroup(SQLiteDatabase inDatabase, String valueCheck){
String query = "SELECT COUNT(id) FROM groups WHERE groupname=\"" + valueCheck + "\"";
Cursor cursor = inDatabase.rawQuery(query, null);
cursor.moveToFirst();
int place = cursor.getInt(0);
return String.valueOf(place);
}
After your query do
int count = 0;
while (cursor.moveToNext()) {
// increment variable
count++;
}
after iterating you will get number of count

Retrieving a database value and assigning to a string value

I am making a app that incorporates login/register functionalities and I'm making a issue that I have been trying to solve.
When a user logins and the login is successful, I'd like to use the email that they signed in with to pass to the next activity using Intent (I checked that the email is in fact getting passed by displaying what is being passed through the intent) and then passing that email to a function in the Dbhelper that uses that email to look for the name of the person that signed in then displaying "Welcome (name of person)" in the current activity but I keep getting a null returned in the function which ultimately leads to the app crashing.
Here is where I'm calling the function in the activity where I want to display the name.
if(!session.loggedIn())
{
Logout();
}
else
{
Intent in = getIntent();
String email = in.getStringExtra("email");
Name.setText("Welcome " + db.findName(email));
}
And this is the function in my DbHelper.java where I'm looking for the name with a query and such.
public String findName(String user_email)
{
String query = "SELECT " + COLUMN_NAME + " FROM " + USER_TABLE + " WHERE " + COLUMN_EMAIL + " = " + "'" + user_email + "'";
SQLiteDatabase db = this.getWritableDatabase();
//reads for database
Cursor c = db.rawQuery(query, null);
c.moveToFirst();
if(c.getCount() > 0) // if cursor is not empty
{
String n = c.getString(0);
return n;
}
else
{
return null;
}
}
As you can see, it's returning null. And yes there is entries in the database already. Also, I tried just passing the email to the function and returning what was passed and it still gave me an error.
Normally, to check for a value in a text column, you do not use the equal = sign, but rather WHERE Column LIKE '%text%'. Also, when saving to a database you should escape and "sanitize" strings. If you did this, then you should also be doing the same process when looking for them, else you won't find them.
I am telling you this since, even if you are sure there are entries in your table, the result of the query may be empty. You could just debug by printing the result of the c.getCount() call or something.

Convert SQLite Database to Java Arraylist

So I've been trying to convert content of a SQLite Database to Objects in an ArrayList. To do that, I've tried to iterate through the Table like written in the code below. But this doesn't return each mark of the specified subject once, but iterates through the table about 70-80 times. I think I know the problem, being that the c.moveToNext moves to the next column of the row and not the next row, but I don't know the solution to this.
public ArrayList<Marks> toMarksList(String subject){
ArrayList<Marks> marksArrayList = new ArrayList<Marks>();
SQLiteDatabase db = getWritableDatabase();
String query = "SELECT * FROM " + TABLE_MARKS + " WHERE " + COLUMN_SUBJECT + "=\"" + subject + "\";";
Cursor c = db.rawQuery(query, null);
c.moveToFirst();
while(!c.isAfterLast()){
if(c.getColumnIndex("subject")!=0){
String dbName = c.getString(c.getColumnIndex("name"));
Double dbValue = c.getDouble(c.getColumnIndex("value"));
Double dbWeight = c.getDouble(c.getColumnIndex("weight"));
marksArrayList.add(new Marks(subject, dbName, dbValue, dbWeight));
}
c.moveToNext();
}
db.close();
return marksArrayList;
}
This code seems to be seriously broken, because it also gets the wrong name for the third entry in the database, but onnly in the first half of the while loops. How do I make it so the cursor is at one row, reads the needed entries of that row and then continues to the next row?
EDIT: Turns out I'm completely stupid and kept adding new entries to the list every time I launched the app.
But this doesn't return each mark of the specified subject once, but iterates through the table about 70-80 times.
I don't see evidence of iterating over the table multiple times.
If that's what you're observing somehow,
it's not in the posted code, but somewhere in the caller of this method.
In any case, I suggest improving the main loop in there, like this:
Cursor c = db.rawQuery(query, null);
while (c.moveToNext()) {
String dbName = c.getString(c.getColumnIndex("name"));
Double dbValue = c.getDouble(c.getColumnIndex("value"));
Double dbWeight = c.getDouble(c.getColumnIndex("weight"));
marksArrayList.add(new Marks(subject, dbName, dbValue, dbWeight));
}
db.close();
See the edit, I just kept adding Data to the Database, which I noticed when the length of the ArrayList kept going up.
Let me just dig a hole and disappear in it.

Fetching single value from SQLite in android

I'm developing my firs app for android right now, I am using multiple tables to get and insert data. during the development and found myself fetching data from the table with has only two columns STATS(_id, stat_name). What my problem is? I have an activity with 10 buttons, and every button correlates with one stat_name. When users presses one of the buttons application is "going" to STATS table to get correct _id and then is inputting this _id to another table GAME_STATS(_id, PlayerId (fk), GameId(fk), StatsId(fk)(andmore)) on STATS._id = GAME_STATS.StatsId and I basicly have to do similar operation for PlayerId.
Right now, I'm doing it this way:
public String getStatId(String statName){
String statId = "Error";
Cursor c = mDb.query(STAT_TABLE, new String[] {AbstractDbAdapter.STAT_ID, AbstractDbAdapter.STAT_NAME}, AbstractDbAdapter.STAT_NAME+ " = " +statName, null, null, null, null);
int count = c.getCount();
if(count == 1){
c.moveToFirst();
statId = c.getString(c.getColumnIndex(AbstractDbAdapter.STAT_ID));
}
c.close();
mDb.close();
Log.d("FootballApp","StatId =" +statId);
return statId;
}
What my problem is, that I know that there SHOULD be only one value returned, and I still have to use Cursor, to do so. Also, in my opinion, it looks way to complicated and time consuming wo write all that code just to get one id from one table. I have 9 tables in my application, and I will have to write similar method every time I need _id from different table when I have, for example, only name.
Can someone tell me if there is easier way to do all that? Please :)
thanks! :)
I think it doesn't get much simpler than that. However you can make the method more generic so you can reuse the code:
public String getFromDb(String tableName, String select, String selectBy, String selectName){
String selection = "Error";
Cursor c = mDb.query(tableName, new String[] {select}, selectBy + "=" + selectName, null, null, null, null);
if(c.getCount() == 1){
c.moveToFirst();
selection = c.getString(c.getColumnIndex(select));
}
c.close();
mDb.close();
Log.d("FootballApp", select + "=" + selection);
return id;
}
Example usage:
int statID = getFromDb(STAT_TABLE, AbstractDbAdapter.STAT_ID, AbstractDbAdapter.STAT_NAME, statName);
That is about as simple as it gets, but Cursor.moveToFirst() returns false if the cursor is empty so you can cut out the c.getCount() call and just say if(c.moveToFirst()) instead. That will save you a little bit of typing :)

Categories

Resources