Deleting from SQLite in Android - java

I have a SQLite DB with a table called "students". In the students table, there are 2 columns: "student_id" and "student_name".
I am trying to delete a row from an SQLite table using this code:
String TABLE_STUDENTS = "students";
String COLUMN_STUDENTNAME= "student_name";
public void deleteUser(String name) {
database.delete(TABLE_STUDENTS, COLUMN_STUDENTNAME + "=" + name, null);
}
However, when I try to delete the user "John" I get this error message from LogCat
12-19 16:28:47.132: E/SQLiteLog(14883): (1) no such column: John
I was trying to follow the example here: Deleting Row in SQLite in Android, but I could swear my syntax is the same.
Guessing I am doing something stupid, but anyone able to help? Thanks.

You may try:
database.delete(TABLE_STUDENTS,COLUMN_STUDENTNAME +" = ?", new String[] { name });

What you are doing is sending the equivalent statement DELETE FROM students WHERE student_name=John, which is why it is looking for a column called John. You need to use the third parameter of the method to provide the argument, so:
final String[] deleteConditions = new String[]{ name };
database.delete(TABLE_STUDENTS, COLUMN_STUDENTNAME + "=?", deleteConditions);
Note that you can delete multiple rows by adding more entries to the array deleteConditions.

That works, although I would recommend
db.delete(TABLE, "column_name=?", new String[] { String.valueOf(custname) });
or use
String query = "DELETE FROM " +TABLE_NAME+ " WHERE " + COLUM_NAME+ " = " + "'"+VALUE +"'" ;
db.execSQL(query);

Related

How to add a value of a variable in a sqlite database existing column?

I would like to ask for some help with my android code. I am trying to develop a quiz app using SQLite.My Database has two Tables. One for Students Information and one for the Questions and answers. Students Information such as Name, Student ID e.c. are inputs through textViews . After taking the Quiz in the Result activity the Score shown up. But i also want this score to be kept in a column COLUMN_SCORE of Student_trable.
I tried to update the table using this method:
`public static void addScore (int StudentScore){
ContentValues cv = new ContentValues();
cv.put(DataContract.StudentTable.COLUMN_SCORE, StudentScore);
Cursor c = db.rawQuery("SELECT * FROM student_info ORDER BY id DESC LIMIT 1 " ,null);
db.update(DataContract.StudentTable.TABLE_NAME1, cv, DataContract.StudentTable.COLUMN_SCORE + "= ?", new String[] {String.valueOf (c)});
db.close();`
but i failed. Any suggestion please?
Here is some more details of my code:
You can use a subquery in the WHERE clause argument of the update() method, so that there is no need for a SELECT query to retrieve the last id:
public static void addScore(int studentScore) {
String table = DataContract.StudentTable.TABLE_NAME1;
String id = DataContract.StudentTable.COLUMN_ID;
ContentValues cv = new ContentValues();
cv.put(DataContract.StudentTable.COLUMN_SCORE, studentScore);
db.update(
table,
cv,
id + " = (SELECT MAX(" + id + ") FROM " + table + ")",
null
);
db.close();
}

Android SQLite rawQuery - How to select multiple rows of a table

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);

Android SQLite specific table row deletion

I have some trouble removing specific users from my SQLite database on my Android device. I made a simple method to delete a table row where table.name equals first input and table.surname equals second input.
Here is my method:
void deleteUser(db_operations opt, String name, String surname) {
SQLiteDatabase sdb = opt.getWritableDatabase();
if(validate(name, surname) == true) {
name = name.replaceAll("\\s+",""); surname = surname.replaceAll("\\s+","");
try {
String DELETE_USER = "DELETE FROM " + tb_users.tb_name + " WHERE " + tb_users.name + "='" + name + "' AND " + tb_users.surname + "='" + surname + "'";
sdb.execSQL(DELETE_USER);
sdb.close();
System.out.println("Deletion SUCCESS!");
} catch (SQLException e) {
System.out.println("Deletion FAILED!");
}
}
}
If I execute a DELETE FROM myTableName statement, every user is removed from the table and from my ScrollView which is ok, but if I execute the above method to remove a specific user, output gives:
Deletion SUCCESS!
but my table still has the record. The record also remains in my ScrollView list (made with LinearLayouts). The list is built dynamically. I've already checked if the data is good or not before my SQLite execution starts and it looks ok. I can't figure out why my method doesn't work. Maybe I've missed something.
(Posted on behalf of the question author).
I got it working. I found out that my validation method was returning false output all the time (I made a typo in one of the conditions), that's why my method never got a chance to execute. Thanks for a reminder to use logs. Was able to track my typo.

Cursors, SQLite, and queries

I have a sqlitedatabase I'm implementing within my app and I keep receiving an IllegalStateException when launching.
09-21 22:48:26.749 15762-16277/nz.co.exium.panther E/AndroidRuntime﹕ FATAL EXCEPTION: SyncAdapterThread-2
java.lang.IllegalStateException: Couldn't read row 0, col 4 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 android.database.CursorWrapper.getString(CursorWrapper.java:114)
at nz.co.exium.panther.sync.PantherSyncAdapter.getRegistrationId(PantherSyncAdapter.java:269)
at nz.co.exium.panther.sync.PantherSyncAdapter.onPerformSync(PantherSyncAdapter.java:64)
at android.content.AbstractThreadedSyncAdapter$SyncThread.run(AbstractThreadedSyncAdapter.java:254)
I believe this is caused by the query returning a fairly empty table (except for _ID that is autoincremented) and then when I attempt to get a String from the cursor.
String registrationID = "";
Uri uri = CustomerEntry.CONTENT_URI;
Cursor cursor = mContext.getContentResolver().query(uri, CUSTOMER_PROJECTION, null, null, null);
if (cursor.moveToFirst()) {
registrationID = cursor.getString(INDEX_CUST_REGID);
}
SQL create table call:
final String SQL_CREATE_CUSTOMER_TABLE = "CREATE TABLE " + CustomerEntry.TABLE_NAME + " (" +
CustomerEntry._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
CustomerEntry.COLUMN_CUST_NAME + " TEXT NOT NULL, " +
CustomerEntry.COLUMN_CUST_EMAIL + " TEXT NOT NULL, " +
CustomerEntry.COLUMN_CUST_QRHASH + " TEXT NOT NULL," +
CustomerEntry.COLUMN_CUST_REGID + " TEXT NOT NULL)";
In this case, the INDEX_CUST_REGID is a final static int related to the position in the String[] projection, 3rd position in this case. It makes sense this would throw but is there a method or way to query the SyncAdapter for a specific column like the CUST_REGID or a method to check if the Column requested was returned before attempting a cursor.getString()?
This also might solve another problem I have with saving the Reg ID before knowing the EMAIL, NAME, QRHASH. Can't insert just one column without the rest having a value as well (NOT NULL), even though it would be worthless data and overwritten asap.
Method attempting to store Reg ID.
private void storeRegistrationID(Context context, String regID) {
//DB insert regid
ContentValues cValues = new ContentValues();
cValues.put(CustomerEntry.COLUMN_CUST_NAME, "");
cValues.put(CustomerEntry.COLUMN_CUST_EMAIL, "");
cValues.put(CustomerEntry.COLUMN_CUST_QRHASH, "");
cValues.put(CustomerEntry.COLUMN_CUST_REGID, regID);
mContext.getContentResolver().insert(CustomerEntry.CONTENT_URI, cValues);
}
projection as requested:
String[] CUSTOMER_PROJECTION = new String[]{
CustomerEntry._ID,
CustomerEntry.COLUMN_CUST_NAME,
CustomerEntry.COLUMN_CUST_EMAIL,
CustomerEntry.COLUMN_CUST_QRHASH,
CustomerEntry.COLUMN_CUST_REGID
};
Are you certain the table was actually created? There's a semi-colon mising from the end of your SQL_CREATE_CUSTOMER_TABLE text string - although I'm not sure if it is mandatory to run the sql for creating the table. I would suggest running it on the Eclipse emulator, then from the DDMS perspective, take a copy of the database somewhere where you can open it with the SQLite Manager plugin for Firefox - this will show you the database tables.

keep column name variable in Java INSERT INTO command with PreparedStatement?

I have the following problem:
I have two tables in one data base which consist of the same columns besides the name of the last column. I want to write data into them using Java.
I want to use the same preparedStatement for both tables, where I check with an if-command whether it is table1 or table2. table2 has amount10 as the name for the last column, table1 has amount20 for it. This number is stored in a variable within my code.
Below you can see a (simplified) example and how I tried to let the column name variable but it doesn't work. Is there any way to fix this without copying the whole statement and manually changing the number variable?
String insertData = "INSERT INTO `database`.`"+table+"`
(`person_id`,`Date`,`amount`+"number") VALUES "+
"(?,?,?) ON DUPLICATE KEY UPDATE " +
"`person_id` = ? , " +
"`Date` = ? , " +
"`amount`+"number" = ? ; ";
PreparedStatement insertDataStmt;
This will not work since variables number and table are not going to be magically injected into your insertData string while you are changing them.
I'd to a method prepareInsertstatement(String table, String number) that would return correct PreparedStatement:
public void prepareInsertStatement(Connection conn, Strint table, String number) {
String insertData = "INSERT INTO `database`.`"+table+"`
(`person_id`,`Date`,`amount+"number"') VALUES "+
"(?,?,?) ON DUPLICATE KEY UPDATE " +
"`person_id` = ? , " +
"`Date` = ? , " +
"`amount+"number"' = ? ; ";
PreparedStatement insertDataStmt = conn.prepareStatement(insertData);
return insertDataStmt;
}
Just remember to close the PreparesStatement when you don't need it any more.
I suppose that reason for that is invalid syntax. When you concatenate string for last column name you use code 'amount' + number. If your number value is 20, than concat result will be
'amount'20 that cause invalid syntax exception. Just move one extra ' after number.
"'amount" + number + "'"
Note: log, or just error that appears during this statement execution would be very useful to find right answer for your question.

Categories

Resources