In my application, I create a table for my database like this :
String action;
action= "CREATE TABLE ";
action+=TABLE_LIEUX;
action+="(Name TEXT NOT NULL PRIMARY KEY);";
base.execSQL(action);
I then add a record to this table with :
ContentValues valeur;
long InsertLine=-10;
valeur=new ContentValues(1);
valeur.put("Name","'"+name+"'");
InsertLine=getWritableDatabase().insert(TABLE_LIEUX,null,valeur);
The value I get for InsertLine is 1, as expected. But when I try to search for the row added with :
result=(SQLiteCursor)getWritableDatabase().query(TABLE_LIEUX,null,"Name='"+name+"'",null,null,null,null);
the SQLiteCursor result I get has a length of -1. And when I try to add the row again, I get an SQLiteException which indicates the row should be unique (so, despite the result of the search, the row is already in the database).
Any idea?
You must force the Cursor to read the returned data (by calling moveToFirst or something like that) before you can get the cursor's record count.
Furthermore, you must not quote values when using the ContentValues put function; the value in the database now contains superfluous quotes.
Why did you cast your query result to (SQLiteCursor)?
Query statements always return a Cursor object so bother with the cast.
Cursor result = getWritableDatabase().
query(TABLE_LIEUX, null, "Name='"+name+
"'", null, null, null, null);
String mString;
if(result != null && c.moveToFirst()) {
mString = result.getString(result.
getColumnIndex("Name"));
}
hope this helps.
Related
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);
I keep getting a NullPointerException when I try this query:
Cursor cursor = sqLiteDatabase.query("collection", new String[] { "SELECT interval WHERE MIN(time) FROM collection" }, null, null,
null, null, null); // This is where the NPE is.
cursor.moveToFirst(); //ADD THIS!
Integer collectionInterval = cursor.getInt(0);
Is my select query right or the way I'm setting this up?
Basically above I want to select an interval where the soonest time to current time from a table. How can I do that?
In a query, FROM comes before WHERE. Also, I think you need an equality test there
SELECT interval FROM collection WHERE time = (SELECT MIN(time) FROM collection)
Hey I have a question:) How can I read only ten rows from my sql db?
here is my code:
openDB();
Cursor c = myDb.getSpalte();
List<Integer> valueList = new ArrayList<Integer>(c.getCount());
while (c.moveToNext()) {
valueList.add(c.getInt(1));
}
c.close();
closeDB();
And if it helps you here is my getSpalte method:
public Cursor getSpalte(){
String where = null;
String Order = "_id DESC";
Cursor c = db.query(true, DATABASE_TABLE, KEY_KALOA,
where, null, null, null, Order, null);
if (c != null) {
c.moveToFirst();
}
return c;
}
Thank yout for helping! And sorry for my bad englsih;P
Set the last null argument to "10". This argument is for LIMIT which limits the number of rows returned by the query.
Cursor c = db.query(true, DATABASE_TABLE, KEY_KALOA,
where, null, null, null, Order, "10");
Remember though that limiting must be accompanied by appropriate logic to sort the result set. Otherwise, you can get any 10 rows, which may not always be what you want.
Reference
Change your db query in your getSpalte function like this:
Cursor c = db.query(true, DATABASE_TABLE, KEY_KALOA,
where, null, null, null, Order, "10");
You can do this by using select TOP, limit or using ROWNUM depending on the DB you use, or you can simple handle it using a simple for loop instead of while.
You can use LIMIT for that as last argument. Here 10.
Refer here
limit - Limits the number of rows returned by the query, formatted as
LIMIT clause. Passing null denotes no LIMIT clause.
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;
}
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 :)