How to avoid duplicate rows in SQLite database in Android? [closed] - java

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 1 year ago.
Improve this question
I am stuck at how do I avoid duplicate rows in Sqlite Database.I tried every possible answer on StackOverflow but none of them worked for me.I tried using unique constraint, db.insertWithOnConflict() but both of them was of no use.
Can anyone please help me to figure out my mistake?
Here is code from my Android studio:
Params.java:
public class Params {
public static final int DB_VERSION=1;
public static final String DB_NAME="PDF_NAME";
public static final String TABLE_NAME="PDF_TABLE";
public static final String KEY_ID="ID";
public static final String KEY_NAME="NAME";
public static final String KEY_PAGE="PAGE";
}
MyDbHandler.java
public class MyDbHandler extends SQLiteOpenHelper {
public static SQLiteDatabase database;
public MyDbHandler(Context context) {
super(context, Params.DB_NAME, null, Params.DB_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
String create="CREATE TABLE "+Params.TABLE_NAME+"("+Params.KEY_ID+" INTEGER PRIMARY KEY,"+Params.KEY_NAME+" TEXT UNIQUE, "
+Params.KEY_PAGE+" INTEGER"+")";
db.execSQL(create);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
public void addPDF(File file)
{
SQLiteDatabase db=this.getWritableDatabase();
ContentValues values=new ContentValues();
values.put(Params.KEY_NAME,file.getName());
values.put(Params.KEY_PAGE, ViewPdf.pagenumber);
db.insertWithOnConflict(Params.TABLE_NAME,null,values,SQLiteDatabase.CONFLICT_REPLACE);
Log.d("pa","pagenumber"+file.getName() + ViewPdf.pagenumber);
Log.d("data","Inserted");
db.close();
}
public Cursor getALlfile()
{
database=this.getReadableDatabase();
String select="SELECT * FROM "+Params.TABLE_NAME;
Cursor cursor=database.rawQuery(select,null);
return cursor;
}
}
DocumentsFragment.java:
public void onItemClick(int position) {
Intent intent = new Intent(getContext(), ViewPdf.class);
intent.putExtra("Position", position);
startActivity(intent);
if (!HistoryFragment.pdfHistory.contains(pdf.get(position))) {
HistoryFragment.pdfHistory.add(0, pdf.get(position));
} else {
File newpdf = pdf.get(position);
int pos = HistoryFragment.pdfHistory.indexOf(newpdf);
HistoryFragment.pdfHistory.remove(pos);
HistoryFragment.pdfHistory.add(0, newpdf);
}
Cursor cursor=MyDbHandler.database.rawQuery("Select * from" + Params.TABLE_NAME + "where"+Params.KEY_NAME+ "=" +(pdf.get(position).getName()) ,null);
if(cursor.moveToFirst())
Toast.makeText(getContext(),"already exist", Toast.LENGTH_SHORT).show();
else{
db.addPDF(pdf.get(position));
}
I am attaching my logcat too if its of any use:
UPDATE
2021-05-08 17:54:15.181 11873-11873/com.flashxpdfreader.flash2021 E/SQLiteLog: (1) no such column: ghty.pdf
2021-05-08 17:54:15.182 11873-11873/com.flashxpdfreader.flash2021 D/AndroidRuntime: Shutting down VM
2021-05-08 17:54:15.183 11873-11873/com.flashxpdfreader.flash2021 E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.flashxpdfreader.flash2021, PID: 11873
android.database.sqlite.SQLiteException: no such column: ghty.pdf (code 1 SQLITE_ERROR): , while compiling: Select * from PDF_TABLE where NAME = ghty.pdf
at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:986)
at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:593)
at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:590)
at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:61)
at android.database.sqlite.SQLiteQuery.<init>(SQLiteQuery.java:37)
at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:46)
at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1443)
at android.database.sqlite.SQLiteDatabase.rawQuery(SQLiteDatabase.java:1382)
at com.flashxpdfreader.flash2021.Fragment.DocumentsFragment.onItemClick(DocumentsFragment.java:156)
at com.flashxpdfreader.flash2021.RecylerAdapter$ViewHolder.lambda$new$0$RecylerAdapter$ViewHolder(RecylerAdapter.java:137)
at com.flashxpdfreader.flash2021.-$$Lambda$RecylerAdapter$ViewHolder$8a1BheGsPwqyn4c_IFEij433NiM.onClick(Unknown Source:2)
at android.view.View.performClick(View.java:7185)
at android.view.View.performClickInternal(View.java:7162)
at android.view.View.access$3500(View.java:819)
at android.view.View$PerformClick.run(View.java:27684)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:224)
at android.app.ActivityThread.main(ActivityThread.java:7562)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:539)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950)
Here is screenshot from my Sqlite database Browser:
You can notice that I actually have that same file name in my Database but it still says no such column.

android.database.sqlite.SQLiteException: near "fromPDF_TABLEwhereNAME": syntax error (code 1 SQLITE_ERROR): , while compiling: Select * fromPDF_TABLEwhereNAME=fhg.pdf
Currently, your sql statement is like this:
Select * fromPDF_TABLEwhereNAME=fhg.pdf
You need to add space. Your sql statement need to be like this:
Select * from PDF_TABLE where NAME = fhg.pdf
In DocumentsFragment.java, try changing the code from
Cursor cursor=MyDbHandler.database.rawQuery("Select * from" + Params.TABLE_NAME + "where"+Params.KEY_NAME+ "=" +(pdf.get(position).getName()) ,null);
To
Cursor cursor=MyDbHandler.database.rawQuery("Select * from " + Params.TABLE_NAME + " where "+Params.KEY_NAME+ " = " +(pdf.get(position).getName()) ,null);

Rather check if your cursor returns something. if the itemcount is != 0 the the pdf exists.
Cursor cursor=MyDbHandler.database.rawQuery("Select * from " + Params.TABLE_NAME + " where "+Params.KEY_NAME+ "=" +(pdf.get(position).getName()) ,null);
if(cursor.getCount() != 0)
Toast.makeText(getContext(),"already exist",Toast.LENGTH_SHORT).show();
else{
db.addPDF(pdf.get(position));
}

Related

My app keep stopping after i added data base code - Android Studio

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.

My android application is getting stopped while running in device

I am a beginner in android development. As per my testing, I found that the app is not running because of following line in MainActivity.java.
tasklist=db.getAllTasks();
here is the main Activity code
<pre><code>
public class MainActivity extends AppCompatActivity implements DialogEndListener{
private ToDoAdapter taskAdapter;
private List<ToDoModel> tasklist;
private Databases db;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Objects.requireNonNull(getSupportActionBar()).hide();
RecyclerView taskRecyclerView = findViewById(R.id.taskRecler);
taskRecyclerView.setLayoutManager(new LinearLayoutManager(this));
taskAdapter=new ToDoAdapter(db,this);
taskRecyclerView.setAdapter(taskAdapter);
tasklist =new ArrayList<>();
FloatingActionButton fab = findViewById(R.id.floatingActionButton);
db=new Databases(this);
db.openDatabse();
ItemTouchHelper itemTouchHelper=new ItemTouchHelper(new ListTouchHandler(taskAdapter));
itemTouchHelper.attachToRecyclerView(taskRecyclerView);
tasklist=db.getAllTasks();
Collections.reverse(tasklist);
taskAdapter.setTasks(tasklist);
fab.setOnClickListener(v -> NewTaskAddition.newInstance().show(getSupportFragmentManager(),NewTaskAddition.TAG));
}
#SuppressLint("NotifyDataSetChanged")
#Override
public void handleDialogClose(DialogInterface dialogInterface) {
tasklist=db.getAllTasks();
Collections.reverse(tasklist);
taskAdapter.setTasks(tasklist);
taskAdapter.notifyDataSetChanged();
}
}
</pre></code>
I think the fault must be in database code.
<pre><code>
public class Databases extends SQLiteOpenHelper {
private static final int VESRSION =1;
private static final String NAME="appDatabase";
private static final String TODO_TABLE="todoTable";
private static final String ID="todoId";
private static final String TASK="taskDesc";
private static final String STATUS="taskStatus";
private static final String CREATE_TODO_TABLE="CREATE TABLE "+ TODO_TABLE+" ( "+ID+
" INTEGER PRIMARY KEY AUTOINCREMENT, "
+ TASK +"TEXT, "+STATUS+
" INTEGER)";
private SQLiteDatabase db;
public Databases(#Nullable Context context) {
super(context, NAME, null, VESRSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREATE_TODO_TABLE); //embedded sql
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
//drop existing table
db.execSQL("DROP TABLE IF EXISTS "+ TODO_TABLE);
onCreate(db);
}
public void openDatabse(){
db=this.getWritableDatabase();
}
public void insertTasks (ToDoModel tasks){
ContentValues value= new ContentValues();
value.put(TASK, tasks.getEachtask());
value.put(STATUS,0);
db.insert(TODO_TABLE,null, value);
}
public List<ToDoModel> getAllTasks(){
List<ToDoModel> taskList =new ArrayList<>();
db.beginTransaction();
try (Cursor sqlcursor = db.query(String.valueOf(Boolean.parseBoolean(TODO_TABLE)), null, null,
null, null, null,
null, null)) {
if (sqlcursor != null) {
if (sqlcursor.moveToFirst()) {
do {
ToDoModel thisTask = new ToDoModel();
thisTask.setId(sqlcursor.getInt(sqlcursor.getColumnIndex(ID)));
thisTask.setEachtask(sqlcursor.getString(sqlcursor.getColumnIndex(TASK)));
thisTask.setStatus(sqlcursor.getInt(sqlcursor.getColumnIndex(STATUS)));
taskList.add(thisTask);
} while (sqlcursor.moveToNext());
}
}
} finally {
db.endTransaction();
}
return taskList;
}
public void updateStatus(int id,int status){
ContentValues value=new ContentValues();
value.put(STATUS,status);
db.update(TODO_TABLE,value,ID+"=?",new String[]{String.valueOf(id)});
}
public void updateTask(int id,String tasks){
ContentValues value=new ContentValues();
value.put(TASK,tasks);
db.update(TODO_TABLE,value,ID+"=?",new String[]{String.valueOf(id)});
}
public void deleteTask(int id){
db.delete(TODO_TABLE,ID+"=?",new String[]{String.valueOf(id)});
}
}
</pre></code>
Can someone help me identifying the error. Thanks in advance.
You are trying to access a table called false or true as you are using String.valueOf(Boolean.parseBoolean(TODO_TABLE)) for the table name (neither table exists).
If you inspected the log then you would have seen something along the lines of :-
2021-10-09 10:49:14.468 25593-25593/a.a.so69499435manager E/SQLiteLog: (1) no such table: false
2021-10-09 10:49:14.468 25593-25593/a.a.so69499435manager D/AndroidRuntime: Shutting down VM
2021-10-09 10:49:14.471 25593-25593/a.a.so69499435manager E/AndroidRuntime: FATAL EXCEPTION: main
Process: a.a.so69499435manager, PID: 25593
java.lang.RuntimeException: Unable to start activity ComponentInfo{a.a.so69499435manager/a.a.so69499435manager.MainActivity}: android.database.sqlite.SQLiteException: no such table: false (code 1 SQLITE_ERROR): , while compiling: SELECT * FROM false
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2913)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3048)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6669)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
Caused by: android.database.sqlite.SQLiteException: no such table: false (code 1 SQLITE_ERROR): , while compiling: SELECT * FROM false
at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:903)
at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:514)
at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588)
at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:58)
at android.database.sqlite.SQLiteQuery.<init>(SQLiteQuery.java:37)
at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:46)
at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1408)
at android.database.sqlite.SQLiteDatabase.queryWithFactory(SQLiteDatabase.java:1255)
at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1126)
at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1332)
at a.a.so69499435manager.Databases.getAllTasks(Databases.java:58)
i.e. the table false could not be found because you query ends up being :-
SELECT * FROM false
You may wish to have a read of https://developer.android.com/studio/debug/#systemLog (and other sections in the linked page)
I believe you should just be using :-
Cursor sqlcursor = db.query(TODO_TABLE, null, null,
null, null, null,
null, null)
However :-
Running a single SQL in a transaction has no benefit.
A Cursor will NEVER be null when returned from any SQliteDatabase method that returns a Cursor, Checking for null is useless.
Try/catch on SQLite more often than not introduces confusion. If an exception occurs then more than likely it MUST be fixed. e.g. you appear to have missed the table false not found error
while(thecursor.moveToNext) { .... } is more concise then a moveToFirst while moveToNext loop.
you should ALWAYS close a cursor when done with it (not doing so may eventually result in a crash because too many Cursors are open).
As such perhaps consider the following :-
public List<ToDoModel> getAllTasks(){
List<ToDoModel> taskList =new ArrayList<>();
Cursor sqlcursor = db.query(TODO_TABLE, null, null,
null,null,null,null,null);
while(sqlcursor.moveToNext()) {
ToDoModel thisTask = new ToDoModel();
thisTask.setId(sqlcursor.getInt(sqlcursor.getColumnIndex(ID)));
thisTask.setEachtask(sqlcursor.getString(sqlcursor.getColumnIndex(TASK)));
thisTask.setStatus(sqlcursor.getInt(sqlcursor.getColumnIndex(STATUS)));
taskList.add(thisTask);
}
sqlcursor.close();
return taskList;
}
More
You may also wish to address the fact that the table will not have a column named taskDesc but will instead have a column named taskDescTEXT as you have omitted a space between the column name and it's type.
Instead of
private static final String CREATE_TODO_TABLE="CREATE TABLE "+ TODO_TABLE+" ( "+ID+
" INTEGER PRIMARY KEY AUTOINCREMENT, "
+ TASK +"TEXT, "+STATUS+
" INTEGER)";
results in
You probably want :-
private static final String CREATE_TODO_TABLE="CREATE TABLE "+ TODO_TABLE+" ( "+ID+
" INTEGER PRIMARY KEY AUTOINCREMENT, "
+ TASK +" TEXT, "+STATUS+ //<<<<<<<<<< ADDED a space before TEXT
" INTEGER)";
results in
If you make this change (add the space). The easy way to do this is to uninstall the App and then rerun it after changing the code. However, you will lose any existing data.
If you need to retain data and apply the change and don't know how then I'd suggest asking another question.

(near "null": syntax error (code 1): , while compiling: INSERT INTO null

I am trying to save data into a database, but it seems that the onCreate method is not run. Might be this might be another problem but the logcat
12-01 01:22:41.785 19724-19724/com.example.user.timetable_test E/SQLiteLog: (1) near "null": syntax error
12-01 01:22:41.795 19724-19724/com.example.user.timetable_test E/SQLiteDatabase: Error inserting _length=1 _name=Break
android.database.sqlite.SQLiteException: near "null": syntax error (code 1): , while compiling: INSERT INTO null(_length,_name) VALUES (?,?)
#################################################################
Error Code : 1 (SQLITE_ERROR)
Caused By : SQL(query) error or missing database.
(near "null": syntax error (code 1): , while compiling: INSERT INTO null(_length,_name) VALUES (?,?))
#################################################################
at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:1058)
at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:623)
at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588)
at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:59)
at android.database.sqlite.SQLiteStatement.<init>(SQLiteStatement.java:31)
at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1607)
at android.database.sqlite.SQLiteDatabase.insert(SQLiteDatabase.java:1479)
at com.example.user.timetable_test.setup.TableDBHandler.addEntry(TableDBHandler.java:79)
at com.example.user.timetable_test.setup.SetTable$PlaceholderFragment$1.onClick(SetTable.java:227)
at android.view.View.performClick(View.java:5697)
at android.widget.TextView.performClick(TextView.java:10826)
at android.view.View$PerformClick.run(View.java:22526)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:158)
at android.app.ActivityThread.main(ActivityThread.java:7225)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
The SQLite class is:
package com.example.user.timetable_test.setup;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
import com.example.user.timetable_test.MiscData;
public class TableDBHandler extends SQLiteOpenHelper{
private MiscData data = MiscData.getInstance();
private static int DATABASE_VERSION = 1;
private static String DATABASE_NAME = "Timetable.db";
private static String[] TABLE_DAY = new String[MiscData.getInstance().getDays()];
private static String COLUMN_SESSION_NUM = "_id";
private static String COLUMN_NAME = "_name";
private static String COLUMN_LENGTH = "_length";
private SQLiteDatabase db;
public TableDBHandler(Context context, String name, SQLiteDatabase.CursorFactory factory,
int version){
super(context, DATABASE_NAME, factory, DATABASE_VERSION);
db = getWritableDatabase();
}
#Override
public void onCreate(SQLiteDatabase sqLiteDatabase){
Log.i("SQL", "DB Created");
for(int i = 0; i < data.getDays(); i++){
TABLE_DAY[i] = data.getDay(i + data.getFirstDay());
}
for(int i = 0; i < data.getDays(); i++){
String query = "CREATE TABLE " + TABLE_DAY[i] + "(" + COLUMN_SESSION_NUM +
" INTEGER PRIMARY KEY ," + COLUMN_NAME + " TEXT," +
COLUMN_LENGTH + " INTEGER " + ");";
sqLiteDatabase.execSQL(query);
}
}
#Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1){
Log.i("SQL", "DB updated");
for(int j = 0; j < data.getDays(); j++){
TABLE_DAY[j] = data.getDay(j + data.getFirstDay());
sqLiteDatabase.execSQL("DROP TABLE EXISTS " + TABLE_DAY[j]);
}
onCreate(sqLiteDatabase);
}
public void addEntry(int day, String name, int length){
ContentValues values = new ContentValues();
values.put(COLUMN_NAME, name);
values.put(COLUMN_LENGTH, length);
SQLiteDatabase db = getWritableDatabase();
db.insert(TABLE_DAY[day], null, values);
db.close();
}
}
I am using an array to create a dynamic number of tables.
The log message in the onCreate method doesn't show up in the logcat, I checked a lot.
Calling the addEntry method:
tableDBHandler.addEntry(page, sessionSpinners[i].getSelectedItem().toString(), Integer.parseInt(lengthText[i].getText().toString()));
If I changed the DATABASE_VERSION from 1 the onUpgrade method is called, but if the version was 1 I cannot see the message from onCreat, in the logcat.
Shouldn't this class create a .db file? Because after clicking the button, and running the method, I can't see any files in the app's folder.
INSERT INTO null - the table name is null. It comes from the TABLE_DAY array you initialize in your SQLite helper onCreate(). But onCreate() is only invoked when the database file is created, not each time you open your database.
You could move the TABLE_DAY init from onCreate() to e.g. constructor.
I am using an array to create a dynamic number of tables.
If the TABLE_DAY array is really dynamic, you're in much more trouble. Consider redesigning your database schema so that the tables are static but the content can be dynamic.

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

sqlite for android, how to update table

I found a number of links on stack overflow dealing with this but none of the solutions have worked for me so here goes:
I am trying to add a column to hold a date (and may need to add a time column in future) but am having some trouble since the table had already been created. Here is the database code:
public class MyDatabase {
public static final String KEY_ROWID = "_id";
public static final String KEY_DATE = "Date";
public static final String KEY_SYS = "Systolic";
public static final String KEY_DIA = "Diastolic";
private static final String DATABASE_NAME = "Blood Pressures";//Used to reference database
private static final String DATABASE_TABLE = "bloodPressureTable";//Tables can be stored in database
// this will be used to store ID, date, systolic and diastolic
private static final int DATABASE_VERSION = 9;
private DbHelper ourHelper;
private final Context ourContext;
private SQLiteDatabase ourDatabase;
public String getData() {
String[] columns = new String[]{KEY_ROWID, KEY_SYS, KEY_DIA};
Cursor c = ourDatabase.query(DATABASE_TABLE, columns, null, null, null, null, null);
String result = "";
int iRow = c.getColumnIndex(KEY_ROWID);
int iSys = c.getColumnIndex(KEY_SYS);
int iDia = c.getColumnIndex(KEY_DIA);
for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext()) { //if cursor is after position of our last entry, then stop
result = result + c.getString(iRow) + //get ROW_ID column, get name of first row and hotness, create new string
" " + c.getString(iSys) + " " +
c.getString(iDia) + "\n";
}
return result;
}
private static class DbHelper extends SQLiteOpenHelper {
public DbHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
//TODO Auto-generated constructor stub
}
#Override
public void onCreate(SQLiteDatabase db) { //This is only called when we first create a database
// when then we will just cycle through onUpgrade, passes a database in
db.execSQL(
"CREATE TABLE " + DATABASE_TABLE + " (" + //create a table called table name
//adds columns inside parenthesise
KEY_ROWID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + //integer increment automatically, referenced by keyID
KEY_DATE + "TEXT NOT NULL, " + //SQL uses the word text rather than string
KEY_SYS + " INTEGER, " +
KEY_DIA + " INTEGER);"
);
}
#Override //called if oncreate has already been called
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
//db.execSQL("DROP TABLE IF EXISTS " + DATABASE_TABLE); //If table name exists it is going
// to drop it and then all we have to do is call our onCreate method
//Removes table added by create table statement
//onCreate(db);
if (newVersion > oldVersion) {
db.execSQL("ALTER TABLE " + DATABASE_TABLE +
" ADD COLUMN " + KEY_DATE + " TEXT NOT NULL, ");
}
}
}
//Constructor below
public MyDatabase(Context c) {
ourContext = c;
}
//open() allows us to open and write to database
public MyDatabase open() {
ourHelper = new DbHelper(ourContext); // this is a new instance of that object passing in the context
ourDatabase = ourHelper.getWritableDatabase();//here we set up our database,
// getting the writeable database. This will open up our database through our helper
return this;
}
public void close() {
ourHelper.close(); //close our SQLiteOpenHelper
}
public long createEntry(int systolic, int diastolic) {
ContentValues cv = new ContentValues();
Calendar c = Calendar.getInstance();
String s = Integer.toString(c.get(Calendar.DAY_OF_MONTH)) + "/" + Integer.toString(c.get(Calendar.MONTH)) +
"/" + Integer.toString(c.get(Calendar.YEAR));
cv.put(KEY_DATE, s);
cv.put(KEY_SYS, systolic);
cv.put(KEY_DIA, diastolic);//Put the string in KEY_NAME column?
return ourDatabase.insert(DATABASE_TABLE, null, cv); //we want this method to return this line
}
}
Can someone advise me of a solution please? As you can see I have tried two different methods (one is commented out in onUpgrade). As you can see I am on version 10 from playing about with it already!
Here is the logcat:
03-02 16:03:48.416 1811-1811/com.dissertation.michael.biolog E/SQLiteLog﹕ (1) Cannot add a NOT NULL column with default value NULL
03-02 16:03:48.416 1811-1811/com.dissertation.michael.biolog D/AndroidRuntime﹕ Shutting down VM
03-02 16:03:48.416 1811-1811/com.dissertation.michael.biolog W/dalvikvm﹕ threadid=1: thread exiting with uncaught exception (group=0x41696bd8)
03-02 16:03:48.416 1811-1811/com.dissertation.michael.biolog E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.dissertation.michael.biolog, PID: 1811
java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=1111, result=-1, data=Intent { (has extras) }} to activity {com.dissertation.michael.biolog/com.dissertation.michael.biolog.MainActivity}: android.database.sqlite.SQLiteException: Cannot add a NOT NULL column with default value NULL (code 1): , while compiling: ALTER TABLE bloodPressureTable ADD COLUMN DateTEXT NOT NULL
at android.app.ActivityThread.deliverResults(ActivityThread.java:3391)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:3434)
at android.app.ActivityThread.access$1300(ActivityThread.java:138)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1284)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:149)
at android.app.ActivityThread.main(ActivityThread.java:5045)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:602)
at dalvik.system.NativeStart.main(Native Method)
Caused by: android.database.sqlite.SQLiteException: Cannot add a NOT NULL column with default value NULL (code 1): , while compiling: ALTER TABLE bloodPressureTable ADD COLUMN DateTEXT NOT NULL
at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:889)
at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:500)
at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588)
at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:58)
at android.database.sqlite.SQLiteStatement.<init>(SQLiteStatement.java:31)
at android.database.sqlite.SQLiteDatabase.executeSql(SQLiteDatabase.java:1672)
at android.database.sqlite.SQLiteDatabase.execSQL(SQLiteDatabase.java:1603)
at com.dissertation.michael.biolog.MyDatabase$DbHelper.onUpgrade(MyDatabase.java:75)
at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:257)
at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:164)
at com.dissertation.michael.biolog.MyDatabase.open(MyDatabase.java:90)
at com.dissertation.michael.biolog.MainActivity.onActivityResult(MainActivity.java:170)
at android.app.Activity.dispatchActivityResult(Activity.java:5430)
at android.app.ActivityThread.deliverResults(ActivityThread.java:3387)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:3434)
at android.app.ActivityThread.access$1300(ActivityThread.java:138)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1284)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:149)
at android.app.ActivityThread.main(ActivityThread.java:5045)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:602)
at dalvik.system.NativeStart.main(Native Method)
03-02 16:03:48.424 1811-1811/com.dissertation.michael.biolog I/Process: Sending signal. PID: 1811 SIG: 9
Alternatively (and preferably if it is simple) a method to delete my table entirely so that version 1 is created again would be ideal. (No useful data has been entered into the database at this point)... Cheers!
Your application is crashing due to java.lang.NumberFormatException: Invalid int: "300-400", it means you are passing invalid format of INTEGER and 300-400 is not a valid int.
P.S. If you want to enter 300-400 into db column use TEXT or VARCHAR(15) as Datatype of your column

Categories