App crash while updating database - java

I'm currently developing an android app with eclipse. I got a problem while updating the database. The problem is the app crash while the updateFlag method is called. The updateFlag method only update one specific column only based on the rowId.
This is my database structure in SQLiteAdapter class:
public long insert(String answer, String question, String hint, String flag, String level){
ContentValues contentValues = new ContentValues();
contentValues.put(KEY_ANSWER, answer);
contentValues.put(KEY_QUESTION, question);
contentValues.put(KEY_HINT, hint);
contentValues.put(KEY_FLAG, flag);
contentValues.put(KEY_LEVEL, level);
return sqLiteDatabase.insert(MYDATABASE_TABLE, null, contentValues);
}
This is the update method in SQLiteAdapter class:
public void updateFlag(long rowId)
{
ContentValues args = new ContentValues();
args.put(KEY_FLAG, "1");
sqLiteDatabase.update(MYDATABASE_TABLE, args, KEY_ROWID + "=" + rowId, null);
}
And this is how I call the updateFlag method in another class:
mySQLiteAdapterListener2 = new SQLiteAdapter(this);
mySQLiteAdapterListener2.openToWrite();
long idListener = Long.parseLong(getId);
mySQLiteAdapterListener2.updateFlag(idListener);
mySQLiteAdapterListener2.close();
What's wrong with my code? Anyone know how to update one specific column based on rowId in the right way?

SQLiteDatabase update method takes four arguments:
database.update(String table_name, ContentValues values, String selection, String[] selectionArgs);
So, your query should be like in your below updateFlag method. Replace your updateFlag method with this one and try this.
public void updateFlag(long rowId)
{
ContentValues args = new ContentValues();
args.put(KEY_FLAG, "1");
sqLiteDatabase.update(MYDATABASE_TABLE, args, KEY_ROWID + "=?", new String[]{rowId+""});
}

Try this:
sqLiteDatabase.update(MYDATABASE_TABLE, args, KEY_ROWID + "=?", new String[] {rowId});
The last parameters if for passing the values that will replace the '?'.
This assumes you have a problem with your update. You need to post a stacktrace so we can see where the app is crashing.

Related

How to insert multiple data in sqlite android studio

hello im newbie in android studio, i have 2 tables DB, first table is budaya and second sejarah. When i try insert data to tables budaya using values put its work, but when i want to insert data to table sejarah the data it doesnt show up, please help me.
here is my bad code
public class Database extends SQLiteOpenHelper{
final static String DB_NAME = "db_budaya";
public Database(Context context) {
super(context, DB_NAME, null, 8);
// TODO Auto-generated constructor stub
}
#Override
public void onCreate(SQLiteDatabase db) {
String sql = "CREATE TABLE IF NOT EXISTS budaya(_id INTEGER PRIMARY KEY AUTOINCREMENT, nama TEXT, kategori TEXT, deskripsi TEXT, img BLOB)";
db.execSQL(sql);
String sql1 = "CREATE TABLE IF NOT EXISTS sejarah(_id INTEGER PRIMARY KEY AUTOINCREMENT, materi TEXT)";
db.execSQL(sql1);
ContentValues values = new ContentValues();
// Budaya table
values.put("_id", "1");
values.put("nama", "Suhunan Jolopong");
values.put("kategori", "Rumah Adat");
values.put("deskripsi", "Suhunan Jolopong, yaitu bentuk bangunan yang atapnya (suhunan) memanjang, sering disebut suhunan panjang atau gagajahan. Bentuk Jolopong sendiri memiliki dua bidang atap. ");
values.put("img", R.drawable.imv_rumahadat_joloponggagajahan);
db.insert("budaya", "_id", values);
ContentValues values1 = new ContentValues();
// Sejarah table
values.put("_id", "1");
values.put("materi", "Hello world");
db.insert("sejarah", "_id", values1);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS budaya");
onCreate(db);
db.execSQL("DROP TABLE IF EXISTS sejarah");
onCreate(db1);
}
}
Please help, Thanks.
You instantiate values1 as the ContentValues object to use to insert the new row in sejarah but you use values which contains the values for the table budaya.
Also there is no need to pass a value for the auto incremented column:
ContentValues values1 = new ContentValues();
values1.put("materi", "Hello world");
db.insert("sejarah", null, values1);
As of now I have only one doubt in your code. You can use below code snippet.
ContentValues values1 = new ContentValues();
// Sejarah table
// values.put("_id", "1"); // <- Comment it
values.put("materi", "Hello world");
db.insert("sejarah", "_id", values1);
Because, values.put("_id", "1"); this line may be the issue, due to you have _id INTEGER PRIMARY KEY AUTOINCREMENT So you don't have to set value implicitly.

How to update entry? SQlite/Android/ToDo App

Learning how to program in android by following a tutorial but i am trying to also update the entry in the data base though not entirely how to do so. Any help please?
package dev.edmt.todolist;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import java.util.ArrayList;
/**
* Created by reale on 06/10/2016.
*/
public class DbHelper extends SQLiteOpenHelper {
private static final String DB_NAME="EDMTDev";
private static final int DB_VER = 1;
public static final String DB_TABLE="Task";
public static final String DB_COLUMN = "TaskName";
public DbHelper(Context context) {
super(context, DB_NAME, null, DB_VER);
}
#Override
public void onCreate(SQLiteDatabase db) {
String query = String.format("CREATE TABLE %s (ID INTEGER PRIMARY KEY AUTOINCREMENT,%s TEXT NOT NULL);",DB_TABLE,DB_COLUMN);
db.execSQL(query);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
String query = String.format("DELETE TABLE IF EXISTS %s",DB_TABLE);
db.execSQL(query);
onCreate(db);
}
public void insertNewTask(String task){
SQLiteDatabase db= this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(DB_COLUMN,task);
db.insertWithOnConflict(DB_TABLE,null,values,SQLiteDatabase.CONFLICT_REPLACE);
db.close();
}
public void editTask(String task){
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(DB_COLUMN,task);
db.update(DB_TABLE,values,DB_COLUMN + " = " + task,null) > 0;
db.close();
}
public void deleteTask(String task){
SQLiteDatabase db = this.getWritableDatabase();
db.delete(DB_TABLE,DB_COLUMN + " = ?",new String[]{task});
db.close();
}
public ArrayList<String> getTaskList(){
ArrayList<String> taskList = new ArrayList<>();
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.query(DB_TABLE,new String[]{DB_COLUMN},null,null,null,null,null);
while(cursor.moveToNext()){
int index = cursor.getColumnIndex(DB_COLUMN);
taskList.add(cursor.getString(index));
}
cursor.close();
db.close();
return taskList;
}
}
More specifically this part, cant really say i quite understand the way it works:
public void editTask(String task){
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(DB_COLUMN,task);
db.update(DB_TABLE,values,DB_COLUMN + " = " + task,null) > 0;
db.close();
}
More specifically this part, cant really say i quite understand the
way it works:
It may work, as in not fail, but as explained below it probably does nothing of any use.
The SQLiteDatabase update method is a convenient way of issuing the SQL to perform an update. It writes/creates the underlying SQl, executes it, and also returns the result (the number of rows updated).
Using your code as an example, to do the similar without using the update method you could create the SQL :-
UPDATE Task SET TaskName = 'your_value' WHERE Task = 'your_value'
Note that this is actually useless as you are effectively saying (assuming for demonstration that the value passed to the editTask method is task001); Update the task row(s) that has/have the value of task001 in the TaskName column to be changed from task001 to task001.
Note the update method uses UPDATE OR IGNORE...... so :-
When an applicable constraint violation occurs, the IGNORE resolution algorithm skips the one row that contains the constraint
violation and continues processing subsequent rows of the SQL
statement as if nothing went wrong. Other rows before and after the
row that contained the constraint violation are inserted or updated
normally. No error is returned when the IGNORE conflict resolution
algorithm is used. SQL As Understood By SQLite - ON CONFLICT clause
Suggestion
Perhaps what would be more useful if say you wanted to change a row that before the update, has a value task001. Changing it say to task002.
in this case the SQL could be :-
UPDATE Task SET TaskName = 'your_new_value' WHERE Task = 'your_original_value'
Your editTask method could then be :-
public void editTask(String original_task, String new_task){
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(DB_COLUMN,new_task);
db.update(DB_TABLE,values,DB_COLUMN + " = '" + original_task + "'" ,null) > 0;
db.close();
}
e.g. using edittask("task001","task002");
Note how the value original_task is enclosed in single quotes.
However, the recommended way, would be to utilise arguments (which would automatically be enclosed in quotes) so the above could be :-
public void editTask(String original_task, String new_task){
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(DB_COLUMN,new_task);
String[] whereargs = new String[]{original_task};
db.update(DB_TABLE,values,DB_COLUMN + "=?",whereargs) > 0;
db.close();
}
each ? coded in the WHERECLAUSE (3rd parameter) replaced by the respective argument in the WHEREARGS (4th parameter) on a 1 by 1 basis.
Additional
In addition to creating the SQL, the update method also invokes the SQL using an appropriate means e.g. it does the equivalent of db.execSQL(your_sql) for you.
Additionally in the case of update it then does the equivalent of :-
Cursor csr = db.rawQuery("SELECT total_changes()",null);
int total_changes = 0;
if(csr.moveToFirst()) {
total_changes = csr.getInt(0);
}
return total_changes;
Hence returning the number of updated rows.
db.update method will create SQL statement according to your given parameters and execute it. You could see the db.update() method to find a better understanding.

Error while updating SQLite Database

I want to update my database where the hotelname = "" (the text in EditText). but i am getting an error in my class file and the sqlitehelper file for the same method {updatedetails())
Where am I going wrong in this?
Here is my code: SQliteHelper class
public int updatedetails(String hotelname, String city, String desc,
String rooms, String price, byte[] image) {
ContentValues updateValues=new ContentValues();
updateValues.put("hotelname", hotelname);
updateValues.put("city", city);
updateValues.put("desc", desc);
updateValues.put("rooms", rooms);
updateValues.put("price", price);
updateValues.put("image", image);
return db.update("Hotel_info", updateValues, "hotelname" + "="
+hotelname, null);
}
And AdminActivity Class:
sqLiteHelper.updatedetails( edtName.getText().toString().trim(),
edtcity.getText().toString().trim(),
edtdesc.getText().toString().trim(),
edtrooms.getText().toString().trim(),
edtPrice.getText().toString().trim(),
imageViewToByte(imageView));
}
});
Try this code:
String[] hotelname= new String[]{hotelname};
db.update("Hotel_info", updateValues, "hotelname=?" , hotelname,null);

retrieve data from sqlite database? [duplicate]

This question already has answers here:
Android Cursor Index out of Bound Exception
(3 answers)
Closed 6 years ago.
I'm trying to retrieve data from sqlite data base but but when I call the nameData() logcat shows the exception:
android.database.CursorIndexOutOfBoundsException: Index 0 requested, with a size of 0
I don't understand why, any clues?
process:
public class SearchContactByName2 extends AppCompatActivity {
String dbString="",dbString2="";
SQLiteDatabase db;
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.searchcontactbynamelayout2_main);
TextView textView=(TextView)findViewById(R.id.textViewShowName);
TextView textView2=(TextView)findViewById(R.id.textView2ShowNumber);
SearchContactByName objOfSearchContactByName=new SearchContactByName();
ContactDatabase onbOfContactDatabase=new ContactDatabase(getBaseContext());
Cursor allcontact2= onbOfContactDatabase.nameData(objOfSearchContactByName.getNameForSearchTypeString);
allcontact2.moveToFirst();
do{
dbString+=allcontact2.getString(allcontact2.getColumnIndex("name"));
dbString2+=allcontact2.getString(allcontact2.getColumnIndex("phone"));
dbString+="\n";
dbString2+="\n";
textView.setText(dbString);
textView2.setText(dbString2);
}while(allcontact2.moveToNext());
Toast.makeText(getBaseContext(), "data", Toast.LENGTH_LONG).show();
}
}
database part:
public class ContactDatabase extends SQLiteOpenHelper {
SQLiteDatabase db;
public static final String DATABASE_NAME="totalContact.db";
public static final String TABLE_NAME="mecontact";
public static final String NAME="name";
public static final String PHONE="phone";
public ContactDatabase(Context context) {
super(context, DATABASE_NAME, null, 1);
}
#Override
public void onCreate(SQLiteDatabase db) {
try {
db.execSQL("create table mecontact" +
"(id integer primary key autoincrement, name text, phone text)");
}catch(android.database.SQLException e){
System.out.println("table create nhi ho rha");
}
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS mecontact");
onCreate(db);
}
public void insertContact(String nam,String mob){
db=this.getWritableDatabase();
ContentValues contentValues=new ContentValues();
contentValues.put(NAME,nam);
contentValues.put(PHONE,mob);
db.insert(TABLE_NAME, null, contentValues);
db.close();
}
public Cursor showData(){
db=this.getWritableDatabase();
Cursor res = db.rawQuery("SELECT * FROM mecontact", null);
return res;
}
public Cursor nameData(String dataName){
db=this.getWritableDatabase();
Cursor res = db.rawQuery("SELECT * FROM mecontact WHERE name = '"+dataName+"'", null);
return res;
}
}
try below code
if(allcontact2.moveToFirst()){
do{
dbString+=allcontact2.getString(allcontact2.getColumnIndex("name"));
dbString2+=allcontact2.getString(allcontact2.getColumnIndex("phone"));
dbString+="\n";
dbString2+="\n";
textView.setText(dbString);
textView2.setText(dbString2);
}while(allcontact2.moveToNext());}
Toast.makeText(getBaseContext(), " no data", Toast.LENGTH_LONG).show();
actually your database has no data
Cursor allcontact2= onbOfContactDatabase.nameData(objOfSearchContactByName.getNameForSearchTypeString);
if(allcontact2.size() > 0){
while(allcontact2.moveToNext()){
dbString+=allcontact2.getString(allcontact2.getColumnIndex("name"));
dbString2+=allcontact2.getString(allcontact2.getColumnIndex("phone"));
dbString+="\n";
dbString2+="\n";
textView.setText(dbString);
textView2.setText(dbString2);
}
Toast.makeText(getBaseContext(), "data", Toast.LENGTH_LONG).show();
}
Along with the answer by sush change nameData method to,
public Cursor nameData(String dataName){
db=this.getReadableDatabase();
//String dataname might contain special characters like a quote
//retreive the cursor this way
Cursor res=db.query("mecontact",new String[]{columnsYouwantToSelect},"name =?",new String[]{dataName},null,null,null);
//if you want to select all the columns in the table replace
//the second parameter with null
return res;
}
Not really answering your question, but more advice on how to prevent trouble in the future. I would suggest you change your oncreate code to this and declare your ID value in the top like you did for the others. This will make sure the database is created correctly and that in the future if changes happen you can easily get values without making typing errors. Code like this is safer to use than pure queries.
db.execSQL("CREATE TABLE "
+ TABLE_NAME
+ " (" + ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"
+ NAME + " TEXT,"
+ PHONE + " TEXT);" );

Using content values to convert string to integer

I am currently working from a project used in a tutorial that displays contacts in a listview. All the fields in the database are used and saved as strings. A custom adapter class is being used for the edit and delete buttons - the buttons appear on the listview, per item. Clicking on edit leads to a separate activity to in which details for that record are parsed in.
I have added another button that I'd like to update a record when clicked and reload the activity. When you press the button it calls a method from the connector method:
public void updateContact(long id, String name, String phone, String mail,
String fb, byte[] blob) {
ContentValues cv = new ContentValues();
cv.put(Contacts.NAME, name);
cv.put(Contacts.PHONE, phone);
cv.put(Contacts.MAIL, mail);
cv.put(Contacts.FB, fb);
cv.put(Contacts.IMAGE, blob);
db = sqlHp.getWritableDatabase();
db.update(Contacts.TABLE, cv, Contacts.ID + "=" + id, null);
db.close();
}
I would like phone to convert the string to an integer, increment the value by 1 and then save using contentvalues as a string. Here is what I've tried:
public void updateContact(long id, String name, String phone,
String mail, String fb, byte[] blob) {
ContentValues cv = new ContentValues();
cv.put(Contacts.NAME, name);
int phone1 = 0;
phone1 = (Integer) cv.getAsInteger(Contacts.PHONE);
phone1++;
phone = String.valueOf(phone1);
cv.put(Contacts.PHONE, phone);
cv.put(Contacts.MAIL, mail);
cv.put(Contacts.FB, fb);
cv.put(Contacts.IMAGE, blob);
db = sqlHp.getWritableDatabase();
db.update(Contacts.TABLE, cv, Contacts.ID + "=" + id, null);
db.close();
}
This gives me a null pointer exception error. I'm not sure where to go from here.
This is the method from the custom adapter which holds the onclick method
setPresent = (ImageButton) v.findViewById(R.id.setPresent);
setPresent.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
sqlCon.updateContact(id, name, phone, email, fb, image);
Intent intent = new Intent(context, MyContactsActivity.class)
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}
});
It's when I click this button the null pointer exception error occurs. These are the lines it flags up:
sqlCon.updateContact(id, name, phone, email, fb, image);
- from the customadapter
and
phone1 = (Integer) cv.getAsInteger(Contacts.PHONE);
- from the connector
This part doesn't really make sense in your code:
ContentValues cv = new ContentValues();
int phone1 = (Integer) cv.getAsInteger(Contacts.PHONE);
You are trying to get Contacts.PHONE from a ContentValues you just created.
Perhaps you wanted to do something like this instead:
cv.put(Contacts.PHONE, Integer.parseInt(phone) + 1);
If you clean up this part, the NullPointerException will probably disappear naturally.
Also, it's safer to update tables using ? placeholders for parameters instead of puttin them in the query string, like this:
db.update(Contacts.TABLE, cv, Contacts.ID + " = ?", new long[]{id});

Categories