Android db.delete(); on ListActivity - java

I need help on a matter...
I created a listview with a cursord adapter that connects to my database,and shows me a list of everything that I saved in my table.
I later created a context menu that appears with longckick on the desired line
context position
id = getListAdapter().getItemId(info.position);
this is my method delete in the databaseHelper
void deleteReg(SQLiteDatabase db)
{
db.delete(TabellaRegistry.TABLE_NAME,null, null);
}
and i use that in my activity for delete the selected line:
final SQLiteDatabase db = databaseHelper.getWritableDatabase();
databaseHelper.deleteReg(db,null, null, null, null, null, null);
but doing so...i delete all in my table...
how do I delete only the selected line via the context menu?
I hope I explained myself, thanks in advance

By passing NULL as your second argument on this line:
db.delete(TabellaRegistry.TABLE_NAME,null, null);
You will always be deleting the whole table. As mentioned in the Android documentation, the parameters are as following:
public int delete (String table, String whereClause, String[] whereArgs)
table - the table to delete from
whereClause - the optional WHERE clause to apply when deleting.
Passing null will delete all rows.
So let's say you want to delete the line where BOOK_ID is 6 you would have something like:
public boolean deleteTitle(String id)
{
return db.delete(DATABASE_TABLE, BOOK_ID + "=" + id, null) > 0;
}
SQLite Class Overview: http://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html

In order to delete specific rows, you need to put a where clause in the delete statement delete

If you check the api docs for this method you can get the answer yourself.
public int delete (String table, String whereClause, String[] whereArgs)
Parameters
table the table to delete from
whereClause the optional WHERE clause to apply when deleting. Passing null will delete all rows.
You are passing null in where clause which is the cause of deleting all records.

Related

Not getting value correct value from sqlite table OR not inserting it properly

I have two sqlite tables in a specific database. I want to add the same data to both tables but on the second table I want to also store the ID of that entry in the first table.
What I do is add the entry ('Name', 'Description') to the first table then query to get the 'ID2' value then add the entry and the ID2 number into my second table after (Put ID2 in as ID3). I always rawquery to get my last entry's 'ID2' column value.
I have this working in the sense that it doesnt crash and does add a value to my second table BUT its isnt adding the value but instead some sort of reference which I do not understand so cant look up.
I would like a solution to get the the last 'ID2' value of my first table and insert it into my second table in 'ID3' column ALSO I would like an explanation of why what I have below is wrong.
Please reference my Java code below and screenshots of my two databases (the second showing the reference code not the value I want)
Thank you so much.
public boolean insetTheme(String name2,String Description){
SQLiteDatabase Mydb =this.getWritableDatabase();
ContentValues newThingAdd = new ContentValues();
newThingAdd.put(COL2_ALLTHEMES,name2);
newThingAdd.put(COL3_ALLTHEMES,Description);
long result = Mydb.insertOrThrow(TABLE_ALLTHEMES,null,newThingAdd);
Cursor res = Mydb.rawQuery("select * from "+TABLE_ALLTHEMES + " where 'ID2'" ,null);
//res.moveToLast();
if (res != null) {
res.move(-1);
}
ContentValues newThingAdd123 = new ContentValues();
newThingAdd123.put(COL2_CURRENTTHEMES,name2);
newThingAdd123.put(COL3_CURRENTTHEMES,Description);
newThingAdd123.put("ID3",res.toString());
long result2 = Mydb.insertOrThrow(TABLE_CURRENTTHEMES,null,newThingAdd123);
if ((result==-1)&(result2==-1))
return false;
else
return true;
}
First Table
Second Table
res is a Cursor so calling toString() on it won't give you what you want.
You need to use res.getString(0) or similar with the specific method based on what type the value is (String, int, boolean etc) and the number being the column number, for example, if the value you want is the third column that would be returned in the query, use res.getString(2) to get the value.
If I made a query like this:
Cursor cursor = Mydb.rawQuery("SELECT * FROM table_1");
and table_1 had 3 columns:
id, name, date
if I wanted the name, I would use
String name = cursor.getString(1);
Hopefully this is what you were after.

SQLite Cursor returning the value for one column as the value for all columns

I am attempting to read from an SQLite database I have created containing information on UK universities.
The table has the following columns:
Institution
Rank_2017
Guardian_score100
Satisfied_with_course
Satisfied_with_teaching
Satisfied_with_feedback
Student_to_staff_ratio
Average_entry_tariff
Career_after_6_months
I have populated the table from a CSV file, and then attempted to call a getUni() method that will return the information in each of the columns, and use them to build a University object, however when I check the values of each member variable of University, the name and rank have been set appropriately, however every variable after that has also been set to the value of Rank_2017.
getUni() Method
public University getUni(String id)
{
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.query(TABLE_UNIVERSITIES, COLUMNS, " Institution = ?",
new String[] { id }, null, null, null, null);
if(cursor != null){
cursor.moveToFirst();
}
System.out.println("###" + cursor.getCount() + "###");
University uni = new University();
if(cursor != null){
uni.setUni_name(cursor.getString(0));
uni.setRank(cursor.getString(1));
uni.setGuardianScore(cursor.getString(2));
uni.setCourseSatisfaction(cursor.getString(3));
uni.setTeachingSatisfaction(cursor.getString(4));
uni.setFeedbackSatisfaction(cursor.getString(5));
uni.setStudentStaffRatio(cursor.getString(6));
uni.setAverageEntryTariff(cursor.getString(7));
uni.setCareerAfterSixMonths(cursor.getString(8));
}
// return University
return uni;
}
After calling cursor.getColumnCount() i can see that it returns 10 columns as expected, however something isn't quite right.
For example, if I call University uni = getUni("Glasgow"); , it will assign both the University name, and rank_2017 correctly, however assign each member variable after that the same as rank_2017.
CSV row example:
Glasgow,26,70.8,89.3,91.6,67.3,14.5,478.4,78.5
Any help solving this issue would be hugely appreciated.
I suspect when you imported the CSV file, it didn't work correctly. Perhaps you didn't specify a separator, and SQLite created a table for you with only one column. Or it populated the table strangely, and your SQL adapter is "helping" in a surprising way. That could happen if for instance your CSV file had some whitespace.
I would use the SQLite shell to verify that the Glassgow row appears as expected in the database. That at least will let you distinguish between SQLite issues and Java library issues (if any).
HTH.

Android: column _id does not exist [duplicate]

I'm having trouble with something that works in the Notepad example.
Here's the code from the NotepadCodeLab/Notepadv1Solution:
String[] from = new String[] { NotesDbAdapter.KEY_TITLE };
int[] to = new int[] { R.id.text1 };
SimpleCursorAdapter notes = new SimpleCursorAdapter(this,
R.layout.notes_row, c, from, to);
This code seems to work fine. But just to be clear, I ran the ADB
utility and run SQLite 3. I inspected the schema as follows:
sqlite> .schema
CREATE TABLE android_metadata (locale TEXT);
CREATE TABLE notes (_id integer primary key autoincrement, title text
not null, body text not null);
All seems good to me.
Now on to my application, which, as far as I can see, is basically the same with
a few minor changes. I've simplified and simplified my code, but the
problem persists.
String[] from = new String[] { "x" };
int[] to = new int[] { R.id.x };
SimpleCursorAdapter adapter = null;
try
{
adapter = new SimpleCursorAdapter(this, R.layout.circle_row, cursor, from, to);
}
catch (RuntimeException e)
{
Log.e("Circle", e.toString(), e);
}
When I run my application, I get a RuntimeException and the following prints
in LogCat from my Log.e() statement:
LogCat Message:
java.lang.IllegalArgumentException: column '_id' does not exist
So, back to SQLite 3 to see what's different about my schema:
sqlite> .schema
CREATE TABLE android_metadata (locale TEXT);
CREATE TABLE circles (_id integer primary key autoincrement, sequence
integer, radius real, x real, y real);
I don't see how I'm missing the '_id'.
What have I done wrong?
One thing that's different between my application and the Notepad example is
that I started by creating my application from scratch using the
Eclipse wizard while the sample application comes already put together. Is
there some sort of environmental change I need to make for a new application
to use a SQLite database?
I see, the documentation for CursorAdapter states:
The Cursor must include a column named _id or this class will not
work.
The SimpleCursorAdapter is a derived class, so it appears this statement applies. However, the statement is technically wrong and somewhat misleading to a newbie. The result set for the cursor must contain _id, not the cursor itself.
I'm sure this is clear to a DBA because that sort of shorthand documentation is clear to them, but for those newbies, being incomplete in the statement causes confusion. Cursors are like iterators or pointers, they contain nothing but a mechanism for transversing the data, they contain no columns themselves.
The Loaders documentation contains an example where it can be seen that the _id is included in the projection parameter.
static final String[] CONTACTS_SUMMARY_PROJECTION = new String[] {
Contacts._ID,
Contacts.DISPLAY_NAME,
Contacts.CONTACT_STATUS,
Contacts.CONTACT_PRESENCE,
Contacts.PHOTO_ID,
Contacts.LOOKUP_KEY,
};
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
// ...
return new CursorLoader(getActivity(), baseUri,
CONTACTS_SUMMARY_PROJECTION, select, null,
Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC");
}
This has been answered and I would like to make it more comprehensive here.
SimpleCursorAdapter requires that the Cursor's result set must include a column named exactly "_id". Don't haste to change schema if you didn't define the "_id" column in your table.
SQLite automatically added an hidden column called "rowid" for every table. All you need to do is that just select rowid explicitly and alias it as '_id' Ex.
SQLiteDatabase db = mHelper.getReadableDatabase();
Cursor cur = db.rawQuery( "select rowid _id,* from your_table", null);
Tim Wu's code really works...
If you are using db.query, then it would be like this...
db.query(TABLE_USER, new String[] {
"rowid _id",
FIELD_USERNAME,
},
FIELD_USERNAME + "=" + name,
null,
null,
null,
null);
Yes , I also change the SELECT string query to fix this issue.
String query = "SELECT t.*,t.id as _id FROM table t ";
What solved my issue with this error was that I had not included the _id column in my DB query. Adding that solved my problem.
This probably isn't relevant anymore, but I just hit the same problem today. Turns out column names are case sensitive. I had an _ID column, but Android expects an _id column.
If you read the docs on sqlite, creating any column of type INTEGER PRIMARY KEY will internally alias the ROWID, so it isn't worth the trouble of adding an alias in every SELECT, deviating from any common utilities that might take advantage of something like an enum of columns defining the table.
http://www.sqlite.org/autoinc.html
It is also more straightforward to use this as the ROWID instead of the AUTOINCREMENT option which can cause _ID can deviate from the ROWID. By tying _ID to ROWID it means that the primary key is returned from insert/insertOrThrow; if you are writing a ContentProvider you can use this key in the returned Uri.
Another way of dealing with the lack of an _id column in the table is to write a subclass of CursorWrapper which adds an _id column if necessary.
This has the advantage of not requiring any changes to tables or queries.
I have written such a class, and if it's of any interest it can be found at https://github.com/cmgharris/WithIdCursorWrapper

Cursor cur = getall();

The following code views all of the records in the database.
Cursor cur = db.getall();
adapter = new RRSelectTrackActivity.MyAdapter(this, cur, this, this);
public MyAdapter(Context context, Cursor c, OnClickListener btnOnClick,OnCheckedChangeListener chkOnChange) {
super(context, R.layout.list_item, c );
this.btnOnClick = btnOnClick;
this.chkOnChange = chkOnChange;
}
I only need to view the first three records. How can I modify this code for that purpose?
The following line executes a query in the background and gets a cursor which lets you move through it one record at a time. You should be interested in the function called in that line instead of the function you wrote to use the data.
Cursor cur = db.getall();
The method that calls the query is the getall(); method on the db instance. So, go to the db class definition and make another method named something like getTopNRecords(int n) that uses the same exact query as getall() except make the query start with select top {n} instead of simply select.
This way, your existing function that uses the data can remain the same, it just has to call a different function than getall() so that it is given less data to work with in the first place.
Some databases don't support the "select top" syntax. In that case, you can usually add "limit {n}" to the query.
Examples:
select top 5 first_name, last_name from people;
select first_name, last_name from people limit 5;

Android update row problems

In the app we are putting together I am trying to update rows from different Activities but it is throwing an error or not updating anything because I can't seem to get the current rowId once I move from one activity to the next. Any thoughts would be great.
This comes from the Activity:
Cursor value;
db.open();
long rowId = value.getLong(value.getColumnIndex("_id"));
boolean id = db.updateA(rowId, a1, a2, a3, a4);
db.close();
If I set the "rowId = 1" it updates that row just fine but I want to get the row that was just created in a different activity.
This is in the DBHelper file:
public boolean updateA(long rowId, String a1,String a2, String a3, String a4) {
ContentValues args = new ContentValues();
args.put(C_A1, a1);
args.put(KEY_A2, a2);
args.put(KEY_A3, a3);
args.put(KEY_A4, a4);
return db.update(TABLE, args, KEY_ROWID + "=" + rowId, null) > 0;
}
If you need to update the record I would suggest storing the record upon creation in a data object in memory and passing that to the other Activity that needs to do the update. The data object should have a property for its own ID, so you can just use that.
Not having a reference to the record you need to update will be a disaster. Also, if you know you always need to update the record, why don't you just do it on insert?
I don't get that.
You have an activity A that opena a DB, updates a row and closes the DB. This is done with the help of SQLiteOpenHelper class.
Now you move to activity B and now what? Post your primary key (you know it, you used it an A) with putExtra to B (or just put the whole row to B). If you put the rowid to B you can open, reread the row, update if needed and close again. If you just put the whole row to B, well that's all you need to do - but I wouldn't like that (e.g. what happens if B crashes?).
If you update in both activities without knowledge what both activities did (and without re-reading the rows) it's pure luck what you end with.
Try this:
return db.update(TABLE, args, KEY_ROWID + "='" + rowId + "'", null)

Categories