RawQuery doesn't work when given null valueto args - java

I'm writing a basic android app in which personal information like name, email, etc. is filled in and stored in an SQLite database by pressing a "submit"-button (this all works perfectly). Then there's a search button which should search for a corresponding person in the database when one field is filled in (e.g. only the field name is given a string "harry" and the other fields keep a null-value). This is the corresponding code in my DatabaseHelper class:
public Person getPerson(String naam, String adres, String email, String geslacht,
String leeftijd, String geboortedatum){
Log.i("Main activity","Person to find: "+naam);
SQLiteDatabase db= this.getReadableDatabase();
Cursor curs=db.rawQuery("SELECT name FROM personen WHERE (name = ?) OR (adress = ?) "
+ "OR (email = ?) OR (gender = ?) OR (age = ?) OR (birthday = ?)",
new String[]{naam, adres, email, geslacht, leeftijd, geboortedatum});
Log.i("Main activity", "Query works");
I used the logs to make sure where the error is thrown and found that the rawQuery does work when all the args[] fields are given a value, but gives an error when one field (e.g. email) contains a null value. Isn't this why I should use the OR statement instead of the AND statement? If not, how can I make it work when not all fields are filled in in the app?

A fast fix should be to do something like that:
new String[]{naam == null? "''":naam, etc}
Check if your sting is initialized, if it is not, replace it by a dummy value.

rawQuery() expects a string array, but null is not a valid string.
You'd have to put the NULL directly into the SQL string, without a parameter.
But when you're constructing the string dynamically anyway, you can just as well leave out that comparison.

search by name:
// Getting single contact
Contact getContact(String name) {
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.query(TABLE_CONTACTS, new String[] { KEY_ID,
KEY_NAME, KEY_PH_NUM }, KEY_NAME + "=?",
new String[] { name }, null, null, null, null);
//...
for access:
Contact contact = null;
if (cursor.moveToFirst()) {
contact = new Contact(Integer.parseInt(cursor.getString(0)),
cursor.getString(1), cursor.getString(2));
}
cursor.close();
// can return null if no contact was found.
return contact;

Related

Can't find the Mistake in my Cursor initialization

And for a bigger APP project I need to work with an SQLite database. If my code works I don't get any data back. And I think I just don't understand the cursor object. In this code I simply want to get a firstname back but it sasy that my cursor is not initialized correctly, but I got the basic code from Android developers. So I can't figure out why it doesn't work.
public String getVorname (String nachname) {
SQLiteDatabase db = this.getReadableDatabase();
String[] projection = {ListeNamen.VORNAME};
String selection =ListeNamen.NACHNAME+" = ?";
String[] selectionArgs ={nachname};
String sortOrder = ListeNamen._ID + " DESC";
Cursor cursor = db.query(ListeNamen.TABLE_NAME,projection,selection,selectionArgs,null,null,sortOrder);
cursor.moveToFirst();
String vorname =cursor.getString(cursor.getColumnIndex(ListeNamen.NACHNAME));
cursor.close();
return vorname;
}
I would get back "Jan" as a String but it shows me this Error
java.lang.IllegalStateException: Couldn't read row 0, col -1 from CursorWindow. Make sure the Cursor is initialized correctly before accessing data from it.
at android.database.CursorWindow.nativeGetString(Native Method)
at android.database.CursorWindow.getString(CursorWindow.java:438)
at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:51)
at com.example.mainaplikation.DBHelper.getVorname(DBHelper.java:58)
at com.example.mainaplikation.MainActivity$1.onClick(MainActivity.java:29)
With this:
String[] projection = {ListeNamen.VORNAME};
you define the columns that you want the query to select.
So you want only the column ListeNamen.VORNAME.
But with this:
String vorname =cursor.getString(cursor.getColumnIndex(ListeNamen.NACHNAME));
you try to retrieve the column ListeNamen.NACHNAME which does not exist in the results.
By the name of the variable vorname I guess you want to do:
String vorname =cursor.getString(cursor.getColumnIndex(ListeNamen.VORNAME));
but since there is only 1 column in the results, you could also do:
String vorname =cursor.getString(0);

How to save email and passowrd value in variable retrieved from select query

I am working on SQLite database. I have retrieved values using select query.
Now I have to save these values in variable for comparison with user entered email ans password.
How can I save it in a variable in Login.java
Query(MYSQLiteHelper.java)
public user_reg getemail(String ema) {
// 1. get reference to readable DB
SQLiteDatabase db = this.getReadableDatabase();
// 2. build query
Cursor cursor =
db.query(TABLE_USERREGISTRATION, // a. table
COLUMNS, // b. column names
" email = ?", // c. selections
new String[] {
String.valueOf(ema)
}, // d. selections args
null, // e. group by
null, // f. having
null, // g. order by
null); // h. limit
// 3. if we got results get the first one
if (cursor != null)
cursor.moveToFirst();
// 4. build book object
user_reg user = new user_reg();
user.setEmail(cursor.getString(3));
user.setPassword(cursor.getString(4));
Log.d("getUser(" + ema + ")", user.toString());
// 5. return book
return user;
}
Login.java
MySQLiteHelper db = new MySQLiteHelper(getApplicationContext());
emailval= email.getText().toString();
db.getemail(emailval);
You can get data from cursor by this way :
// 3. if we got results get the first one
if (cursor != null)
cursor.moveToFirst();
// 4. build book object
user_reg user = new user_reg();
// I am expecting email and password as column name
user.setEmail(cursor.getString(cursor.getColumnIndex("email")));
user.setPassword(cursor.getString(cursor.getColumnIndex("password")));
Log.d("getUser(" + ema + ")", user.toString());
// 5. return book
return user;
You need to check like this for your username if exist or not ..
if(ema.equals(cursor.getString(3))){
user.setEmail(cursor.getString(3));
user.setPassword(cursor.getString(4));
} else{
.....
}

SQLite Java Android no such table, program crashes

I'm trying to make database for my program and I'm having a lot of dumb problems...
It's fragment of main activity:
Database db = new Database(this,editText.getText().toString());
String text = db.printRow();
textView.setText(text);
Now database class:
String nickname="EmptyNick";
public Database(Context context, String name) {
super(context, "database.db", null, 1);
nickname = name;
}
public void onCreate(SQLiteDatabase db) {
if(!nickname.equals("EmptyNick")) {
db.execSQL("create table player(id integer primary key autoincrement,nick text);");
Users user = new Users();
user.setNick("Mariusz");
addPlayer(user);
}
else {
//not important
}
}
private void addPlayer(Users user) {
SQLiteDatabase db = getWritableDatabase();
ContentValues values = new ContentValues();
values.put("nick",user.getNick());
db.insertOrThrow("player",null,values);
}
public String printRow() {
String string=null;
if(!nickname.equals("EmptyNick")) {
String[] collumns = {"id","nick"};
SQLiteDatabase db = getReadableDatabase();
Cursor cursor = db.query("player",collumns,null,null,null,null,null);
cursor.moveToFirst();
while (cursor.moveToNext()) {
string += cursor.getString(1);
}
}
else {
//not important
}
return string;
}
Errors:
no such table: player
Caused by: java.lang.reflect.InvocationTargetException
Caused by: android.database.sqlite.SQLiteException: no such table: player (code 1): , while compiling: SELECT id, nick FROM player
I really can't see what's wrong. Error says there is no table 'player', but it is. On the beggining of onCreate methon in line:
db.execSQL("create table player(id integer primary key autoincrement,nick text);");
Can somebody help me? If I make Toast instead of text.setText(...) it shows me empty field, so yes, it can't create specific row. I understand the error, but do not from where and why it comes.
The table you try to use does not exist. In such cases it is generally a good idea to check the database you are using and check whether the table exists. In this particular case it seems that you create the table if a condition is met. The condition is that your nickname's value differs from the default value. However, it does not differ. Make sure that you use a table if and only if it exists and you have the correct condition for creating the table.
I don't really understand your problem. If there is an error, it will throw an ANR message, how can you print the toast and it shows the empty? and the Toast showed empty because you add only one record of data to your table, then in your printRow(), you called cursor.moveToFirst, then you call while(cursor.moveToNext()) which will move your cursor to second row and it will return false since you only have 1 record.

SQLite Cursor getColumnIndex() returning -16 even when column exists

I'm storing a number of objects for my app in an SQLite Database. The class for these objects has a constructor that takes a Cursor object, passed in from the Database class. Example:
public MyClass(Cursor cursor) {
this.id = cursor.getString(cursor.getColumnIndex(MyDatabase.KEY_ROWID));
this.nickname = cursor.getString(cursor.getColumnIndex(MyDatabase.KEY_NICKNAME));
...and so on.
However I've noticed that at random times I've been getting a crash when getColumnIndex for the ID column returns -16. (And if I comment out that line, whichever the first column I try to access is, it will also return -16). I've added some extra logging around it but it hasn't helped as it seems like the columns are fine:
public MyClass(Cursor cursor) {
Log.i("TEST", Column names are: " + Arrays.toString(cursor.getColumnNames()));
Log.i("TEST", Making object, id column index is " + cursor.getColumnIndex(MyDatabase.KEY_ROWID));
Which prints:
Column names are: [_id, nickname...]
Making object, id column index is -16
So it sees like everything should be fine, anyone got any clue why everything could be getting so messed up while reading from the Cursor?
EDIT: Here's how I'm getting the cursor, this is a method in the database class:
public MyObject getMyObject(String id) {
MyObject objectFound = null;
String[] whereArgs = { id };
Cursor cursor = db.query(true, getTableName(), null, WHERE_EQUALS, whereArgs, null, null, null, null);
if(cursor.moveToFirst()) {
//Should only return 1 entry from DB
while(cursor.isAfterLast() == false) {
objectFound = new MyObject(cursor);
cursor.moveToNext();
}
}
cursor.close();
return objectFound;
}

Android SQLite SELECT Query

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.

Categories

Resources