*
My problem
Recently, I ran some of my Java code [Open Helper] through android studio , and it gave the following error :
I have an login page with android (java code) and just my problem when time that must be password just string put , will be true. but if was put numerical password , will not true .
code SqlOpenHelper
package com.example.root.sql2;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.support.annotation.Nullable;
public class db extends SQLiteOpenHelper {
public db(Context context) {
super(context, "login.db", null, 1);
}
#Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {
sqLiteDatabase.execSQL("CREATE TABLE USER(ID INTEGER PRIMARY KEY AUTOINCREMENT ,NAME TEXT, PASSWORD TEXT)");
}
#Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
sqLiteDatabase.execSQL("DROP TABLE IF EXISTS USER");
onCreate(sqLiteDatabase);
}
public boolean insert (String name , String password){
SQLiteDatabase db = getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put("NAME", name);
contentValues.put("PASSWORD", password);
long ins = db.insert("USER","",contentValues);
if (ins == -1) return false;
else return true;
}
public boolean login(String name , String password){
SQLiteDatabase db = getReadableDatabase();
Cursor cursor = db.rawQuery("SELECT * FROM USER WHERE NAME=? AND PASSWORD=?", new String[] {name , password});
cursor.moveToFirst();
if (cursor.getCount()>0) return false;
else return true;
}
}
"password" if was string ,password then is true but "password" if was string ,password(numerical) then will not true ...
*
I believe your main issue is that your logic is reversed.
You are basically saying by using if (cursor.getCount()>0) return false;; if the search for the user found the user then return false.
I believe you want if (cursor.getCount()>0) return true;
However, albeit it not an issue, the use of moveToFirst adds nothing of use. Additionally you may encounter issues because you are not closing the cursor.
I'd suggest that you perhaps use :-
public boolean login(String name , String password){
SQLiteDatabase db = getReadableDatabase();
Cursor cursor = db.rawQuery("SELECT * FROM USER WHERE NAME=? AND PASSWORD=?", new String[] {name , password});
int count = cursor.getCount();
cursor.close();
return count > 0;
}
This gets the count, closes the cursor, then returns true if the count is greater than 0 (user password combination was found) otherwise false;
Related
I don't know what is the problem of my database, my app keep stopping after i added the data base code.
Please can you help with to fix that.
I have tried many times to figure it out but still not getting anywhere.
This is my data base code :
public class databaseOpenHelper extends SQLiteOpenHelper{
// Country table name
private static final String TABLE_NAME= "contacts";
// Country Table Columns names
private static final String KEY_ID = "id";
private static final String NAME = "Name";
private static final String PHONENO = "PhoneNo";
public databaseOpenHelper(Context context){
super(context,"Login.db",null,1);
}
#Override
public void onCreate(SQLiteDatabase myDB) {
myDB.execSQL("create Table users(username Text primary key,password Text)");
// create the table for the first time
String CREATE_COUNTRY_TABLE = "CREATE TABLE " + TABLE_NAME + "("
+ KEY_ID + " INTEGER PRIMARY KEY," + NAME + " TEXT,"
+ PHONENO + " TEXT" + ")";
myDB.execSQL(CREATE_COUNTRY_TABLE);
}
#Override
public void onUpgrade(SQLiteDatabase myDB, int i, int i1) {
myDB.execSQL("drop Table if exists users");
}
public Boolean isertData(String username,String password){
SQLiteDatabase myDB = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put("username",username);
contentValues.put("password",password);
long result = myDB.insert("users",null,contentValues);
if(result == -1){
return false;
}
else {
return true;
}
}
public Boolean checkusername(String username){
SQLiteDatabase myDB = this.getWritableDatabase();
Cursor cursor = myDB.rawQuery("select * from users where username = ?",new String[] {username});
if (cursor.getCount()>0){
return true;
}
else {
return false;
}
}
public Boolean checkusernamePassword(String username,String password){
SQLiteDatabase myDB = this.getWritableDatabase();
Cursor cursor = myDB.rawQuery("select * from users where username = ? and password = ?",new String[] {username,password});
if (cursor.getCount()>0){
return true;
}
else{
return false;
}
}
// method to add the contact
public void addcontact(ContactModel contact){
SQLiteDatabase db=this.getWritableDatabase();
ContentValues c=new ContentValues();
c.put(NAME,contact.getName());
c.put(PHONENO,contact.getPhoneNo());
db.insert(TABLE_NAME,null,c);
db.close();
}
// method to retrieve all the contacts in List
public List<ContactModel> getAllContacts(){
List<ContactModel> list=new ArrayList<>();
String query="SELECT * FROM "+TABLE_NAME;
SQLiteDatabase db=this.getReadableDatabase();
Cursor c=db.rawQuery(query,null);
if(c.moveToFirst()) {
do {
list.add(new ContactModel(c.getInt(0),c.getString(1),c.getString(2)));
} while (c.moveToNext());
}
return list;
}
// get the count of data, this will allow user
// to not add more that five contacts in database
public int count(){
int count=0;
String query="SELECT COUNT(*) FROM "+TABLE_NAME;
SQLiteDatabase db = this.getReadableDatabase();
Cursor c=db.rawQuery(query,null);
if(c.getCount()>0){
c.moveToFirst();
count=c.getInt(0);
}
c.close();
return count;
}
// Deleting single country
public void deleteContact(ContactModel contact) {
SQLiteDatabase db = this.getWritableDatabase();
int i=db.delete(TABLE_NAME,KEY_ID + " = ?",
new String[] { String.valueOf(contact.getId()) });
db.close();
}
}
And this is my logcat :
FATAL EXCEPTION: main
Process: com.example.localisation, PID: 11700
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.localisation/com.example.localisation.phone}: android.database.sqlite.SQLiteException: no such table: contacts (code 1 SQLITE_ERROR): , while compiling: SELECT * FROM contacts
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3635)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3792)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:103)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2210)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loopOnce(Looper.java:201)
at android.os.Looper.loop(Looper.java:288)
at android.app.ActivityThread.main(ActivityThread.java:7839)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
Caused by: android.database.sqlite.SQLiteException: no such table: contacts (code 1 SQLITE_ERROR): , while compiling: SELECT * FROM contacts
at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:1047)
at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:654)
at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:590)
at android.database.sqlite.SQLiteProgram.(SQLiteProgram.java:62)
at android.database.sqlite.SQLiteQuery.(SQLiteQuery.java:37)
at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:46)
at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1546)
at android.database.sqlite.SQLiteDatabase.rawQuery(SQLiteDatabase.java:1485)
at com.example.localisation.databaseOpenHelper.getAllContacts(databaseOpenHelper.java:108)
at com.example.localisation.phone.onCreate(phone.java:81)
at android.app.Activity.performCreate(Activity.java:8051)
at android.app.Activity.performCreate(Activity.java:8031)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1329)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3608)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3792)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:103)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2210)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loopOnce(Looper.java:201)
at android.os.Looper.loop(Looper.java:288)
at android.app.ActivityThread.main(ActivityThread.java:7839)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
The failure is saying that there is not a table called contacts as per
Caused by: android.database.sqlite.SQLiteException: no such table: contacts (code 1 SQLITE_ERROR): , while compiling: SELECT * FROM contacts
Running your code and then using the errant getAllContacts method, as indicated in the log by:-
at com.example.localisation.databaseOpenHelper.getAllContacts(databaseOpenHelper.java:108)
Works.
As such it is highly likely that you have added the contacts cable after previously running the App and that this has created the database. The database persists and thus will still exist from on run to the other. As such the onCreate method will not be called, as it is only called once when the database is created.
The easy fix is to uninstall the App and rerun. However, this will delete any existing data.
If you need to keep any data then you should a) increase the version number and then b) add code to the onUpgrade method to create the new table (same code).
For example:-
a)
public databaseOpenHelper(Context context){
super(context,"Login.db",null,2 /*<<<<<<<<<< CHANGED */);
}
b)
#Override
public void onUpgrade(SQLiteDatabase myDB, int i, int i1) {
//myDB.execSQL("drop Table if exists users");
if (i1 == 2) {
String CREATE_COUNTRY_TABLE = "CREATE TABLE " + TABLE_NAME + "("
+ KEY_ID + " INTEGER PRIMARY KEY," + NAME + " TEXT,"
+ PHONENO + " TEXT" + ")";
myDB.execSQL(CREATE_COUNTRY_TABLE);
}
}
You can the see that the contacts table has been created by using App Inspection e.g.
according to the error code you uploaded i noticed this SELECT * FROM contacts which means that you don't have table named contacts in you sqlite database so i recommend you, for testing you should use sqlite browser to create database and add data to it and then use it in your android studio project. if you get any problem fearther don't hesitate to ask it in comments thanks.
I'm trying to insert data into related tables, but I've searched many forums and no option works for me, I'm just starting out with this.
The tables are the following:
Table 1:
form CREATE TABLE(
form_id int(11) PRIMARY KEY,
dateCreation date NOT NULL);
tables 2:
create table form_mvdrecinto(
id_mvdrecinto INTEGER PRIMARY KEY AUTOINCREMENT,
fk_form_id int(11) not null,
long varchar(20) not null,
FOREIGN KEY(id_formulario_fk) REFERENCES form(id_form));
In the save method is where I have the problem, specifically in the ContentValues, how the exact statement should be in my case to insert the data in both related tables.
Thank you.
The method is the convenience insert method which simplifies the construction of INSERT SQL statements based upon a ContentValues.
SQL does not allow the insertion of rows into multiple tables. So you cannot insert into both tables in a single use of the insert method. Furthermore the insertion into the form_mvdrecinto requires you to know the value of the foreign key.
First you have various problems with the SQL.
I believe that you need/want something like ():-
CREATE TABLE IF NOT EXISTS form /* TABLE NAME AFTER, NOT BEFORE THE CREATE KEYWORD/CLAUSE */(form_id int(11) PRIMARY KEY, dateCreation date NOT NULL);
CREATE TABLE IF NOT EXISTS form_mvdrecinto(
id_mvdrecinto INTEGER PRIMARY KEY AUTOINCREMENT,
fk_form_id int(11) not null,
long varchar(20) not null,
FOREIGN KEY (fk_form_id /*<<<<< MUST BE A COLUMN IN THE TABLE */) REFERENCES form(form_id /*<<<<< pretty sureyou want to reference form_id column not the non-existent id_form column*/)
);
Assuming What you would do as an example is to have a method based upon:-
void saveFormWithRelatedFormmvdrecinto(long formId, String date, String _long) {
ContentValues cv = new ContentValues();
cv.put("form_id,formId);
cv.put("date",date);
db.insert("form",null,cv);
cv.clear();
cv.put("fk_form_id",formId);
cv.put("long",_long);
db.insert("form_mvdrecinto",null,cv);
}
obviously db is an SQLiteDatabase.
due to the ForeignKey constraint the form must be inserted prior to the formmvdrecinto (or formmvdrecintos are inserted).
As the SQLiteDatabase insert Method uses INSERT OR IGNORE ...., the above could be used for an existing form, it would simply ignore inserting the duplicate form and then continue to insert the formmdvrecinto.
It appears that you may have the misconception that FOREIGN KEY builds relationships automatically. It DOES NOT (it cannot) you have to indicate the actual relationship. FOREIGN KEY is a constraint, a rule, that says that the column(s) in the table with the foreign key MUST contain a value that exists in the REFRENECED column(s) in the REFRENCED TABLE otherwise a conflict (failure) will result. INSERT OR IGNORE does not ignore such a conflict.
Demonstration
The following is a working demonstration based upon the tables above. In addition to using a known form id for the insertion of form_mvdrecinto rows (it ads 2 such rows). It also demonstrates a more precarious insertion based upon the dateCreated (if not unique then the form_mvdrecinto inserted will be an arbritary row where the datecreated is matched).
First most of the code is in the DatabaseHelper class it being :-
class DatabaseHelper extends SQLiteOpenHelper {
public static final String DATABASE_NAME = "the_database.db";
public static final int DATABASE_VERSION = 1;
public static final String FORM_TABLE = "form";
public static final String COL_FORM_FORMID = "form_id";
public static final String COL_FORM_DATECREATION = "date_creation";
public static final String FORM_MVDRECINTO_TABLE = "form_mvdrecinto";
public static final String COL_FORMMVDRECINTO_FORMMVDRECINTO_ID = "id_mvdrecinto";
public static final String COL_FORMMVDRECINTO_FK_FORM_ID = "fk_form_id";
public static final String COL_FORMMVDRECINTO_LONG = "long";
private static volatile DatabaseHelper instance = null;
private SQLiteDatabase db;
private DatabaseHelper(Context context) {
super(context, DATABASE_NAME,null, DATABASE_VERSION);
db = this.getWritableDatabase();
/* By defauly Foreign Keys are not turned no, so turn them on */
db.setForeignKeyConstraintsEnabled(true);
}
public static DatabaseHelper getInstance(Context context) {
if (instance == null) {
instance = new DatabaseHelper(context);
}
return instance;
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(
"CREATE TABLE IF NOT EXISTS " + FORM_TABLE + " ("
+ COL_FORM_FORMID + " INTEGER PRIMARY KEY "
+"," + COL_FORM_DATECREATION + " date NOT NULL"
+ ");"
);
db.execSQL(
"CREATE TABLE IF NOT EXISTS " + FORM_MVDRECINTO_TABLE +"("
+ COL_FORMMVDRECINTO_FORMMVDRECINTO_ID + " INTEGER PRIMARY KEY"
+ "," + COL_FORMMVDRECINTO_FK_FORM_ID + " INTEGER NOT NULL"
+ "," + COL_FORMMVDRECINTO_LONG + " TEXT NOT NULL"
+ ", FOREIGN KEY (" + COL_FORMMVDRECINTO_FK_FORM_ID + ") REFERENCES " + FORM_TABLE + "(" + COL_FORM_FORMID + ")"
+ ");"
);
}
public long insertForm(Long id, String dateCreated) {
ContentValues cv = new ContentValues();
if (id != null && id > 0) {
cv.put(COL_FORM_FORMID,id);
}
cv.put(COL_FORM_DATECREATION,dateCreated);
return db.insert(FORM_TABLE,null,cv);
}
public long insertForm(String dateCreated) {
return insertForm(null,dateCreated);
}
public long insertFormMVDRecinto(Long id, long form_id, String _long) {
ContentValues cv = new ContentValues();
if (id != null && id > 0) {
cv.put(COL_FORMMVDRECINTO_FORMMVDRECINTO_ID,id);;
}
cv.put(COL_FORMMVDRECINTO_FK_FORM_ID,form_id);
cv.put(COL_FORMMVDRECINTO_LONG,_long);
return db.insert(FORM_MVDRECINTO_TABLE,null,cv);
}
public long insertFormMVDRecinto(long form_id, String _long) {
return insertFormMVDRecinto(null,form_id,_long);
}
#SuppressLint("Range")
public long insertFormMVDRecinto(Long id, String dateCreated, String _long) {
long rv = -1;
Cursor csr = db.query(FORM_TABLE,new String[]{COL_FORM_FORMID},COL_FORM_DATECREATION + "=?",new String[]{dateCreated},null,null,null,"1");
if (csr.moveToFirst()) {
rv = insertFormMVDRecinto(id,csr.getLong(csr.getColumnIndex(COL_FORM_FORMID)),_long);
}
return rv;
}
#Override
public void onUpgrade(SQLiteDatabase db, int i, int i1) {
}
}
To actually demonstrate the following MainActivity is an activity which :-
Adds 3 Form rows
Adds 3 Form_mvdrecinto rows
The first two being added using the known form_id.
The last is added according to a known dateCreated value.
Tries to add a 4th Form_mdvrecinto row BUT with a dateCreated that IS NOT in any rows (due to the no row being extracted the attempt to insert a row which would result in a FK conflict is not attempted).
:-
public class MainActivity extends AppCompatActivity {
DatabaseHelper dbhelper;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
dbhelper = DatabaseHelper.getInstance(this);
long f1 = dbhelper.insertForm(10L,"2021-02-10 10:21:13"); /* id will be 10 */
long f2 = dbhelper.insertForm("2021-02-10 11:13:55"); /* id will probably be 11 */
long f3 = dbhelper.insertForm(1000l,"2021-02-10 09:00:00");
long fm1 = dbhelper.insertFormMVDRecinto(f1,"Blah001");
long fm2 = dbhelper.insertFormMVDRecinto(100l,f1,"Blah002");
/* WARNING if more than 1 form with 2021-02-10 09:00:00 then could be related to any 1 */
long fm3 = dbhelper.insertFormMVDRecinto(null,"2021-02-10 09:00:00","Blah003");
/* WILL NOT INSERT as no such dateCreated value in the Form table*/
/* does not attempt to insert into the Form_mdvrecinto because the row is not found/extracted */
long fm4 = dbhelper.insertFormMVDRecinto(null,"NOT A DATE THAT WOULD EXIST","Blah004");
}
}
Sorry if this is a stupid question but I am new to Android Development. I am trying to create a login screen which will direct doctors to a one activity and nurses to another activity when they login. This does not seem to work. I have put code into the login.java class:
btLogin.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
String email = loginemail.getText().toString();
String password = loginpassword.getText().toString();
Boolean Chkemailpass = db.emailpassword(email, password);
if(Chkemailpass == true) {
Cursor typeofuser;
typeofuser = db.checkUser(loginemail.getText().toString()); //get user type from database
if(typeofuser.equals("Nurse")) {
Intent mainintent = new Intent(Login.this, NurseHome.class);
startActivity(mainintent);}
else if (typeofuser.equals("Doctor")){
Intent intent = new Intent(Login.this, DoctorHome.class);
startActivity(intent);}
}
else
Toast.makeText(getApplicationContext(),"Wrong email or password", Toast.LENGTH_SHORT).show();
}
});
}
}
And I also have this code in the databasehelper class relating to the usertype:
public Cursor checkUser(String email) {
SQLiteDatabase db = this.getReadableDatabase();
Cursor res = db.rawQuery("SELECT TYPEOFUSER from user_table WHERE EMAIL=email", null);
return res;
}
All help would be appreciated, thank you.
The argument email of checkUser() is a string, so in your sql statement it should be enclosed inside single quotes like this:
SELECT TYPEOFUSER from user_table WHERE EMAIL = 'email'
but the correct way to pass parameters to rawQuery() is with the use of ? placeholders and the use of the 2nd argument as an array of string parameters (instead of null).
Also don't return the Cursor, but the type of user as a String from checkUser().
So change to this:
public String checkUser(String email) {
String result = "";
SQLiteDatabase db = this.getReadableDatabase();
Cursor res = db.rawQuery(
"SELECT TYPEOFUSER from user_table WHERE EMAIL = ?",
new String[] {email}
);
if (res.moveToNext()) {
result = res.getString(0);
}
res.close();
return result;
}
and instead of:
Cursor typeofuser;
typeofuser = db.checkUser(loginemail.getText().toString());
use this:
String typeofuser = db.checkUser(loginemail.getText().toString());
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.
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);" );