Retrieving row data from SQLite Db based on Unique Identifier - java

I have implemented an SQLite DB into my app and i am trying to write functions that will retrieve the data in a row associated with the unique identifier. I have tried a lot of stackoverflow answers and none seem to be working in my situation.
I have a database helper class where i have created the database through code and am writing the functions. See code below:
public class DatabaseHelper extends SQLiteOpenHelper {
public static final String DATABASE_NAME = "TrackerNew.db";
public static final String TABLE_NAME = "tracker_new_table";
public static final String COL_2 = "LINETYPE";
public static final String COL_3 = "PACKAGETYPE";
public static final String COL_4 = "QUANTITY";
public static final String COL_5 = "DURATION";
public static final String COL_6 = "STARTTIME";
public static final String COL_7 = "ENDTIME";
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, 1); }
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("create table " + TABLE_NAME +" (LINETYPE TEXT PRIMARY KEY,PACKAGETYPE TEXT,QUANTITY TEXT,DURATION TEXT,STARTTIME TEXT,ENDTIME TEXT)");
}
#Override
public void onUpgrade(SQLiteDatabase db, int i, int i1) {
db.execSQL("DROP TABLE IF EXISTS "+TABLE_NAME);
onCreate(db);
}
public boolean insertData(String linetype, String packagetype, String quantity, String duration, String starttime, String endtime) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(COL_2,linetype);
contentValues.put(COL_3,packagetype);
contentValues.put(COL_4,quantity);
contentValues.put(COL_5,duration);
contentValues.put(COL_6,starttime);
contentValues.put(COL_7,endtime);
long result = db.insert(TABLE_NAME,null,contentValues);
if(result == -1)
return false;
else
return true;
}
//FUNCTIONS TO GET DATA BY ROW
public Cursor getAllData() {
SQLiteDatabase db = this.getWritableDatabase();
Cursor res = db.rawQuery("select * from "+TABLE_NAME,null);
return res;
}
public Cursor getProgressBar1() {
SQLiteDatabase db = this.getWritableDatabase();
Cursor res = db.query("select * from "+ TABLE_NAME + "where" + COL_2="S1");
return res;
}
public Cursor getProgressBar2() {
SQLiteDatabase db = this.getWritableDatabase();
Cursor res = db.query("select * from "+ TABLE_NAME + "where" + COL_2="S2");
return res;
}
}
If you can see my functions at the bottom of my code i am trying to write raw queries to get the data by ID( S1,S2 Etc.)
Can anyone help me out with the code inside these functions?
Thanks!

The issue is that you are trying to create a string using:-
"select * from "+ TABLE_NAME + "where" + COL_2="S1"
This will not compile because you have misplaced the = and overwritten or omitted the + concatenation. I believe that you should have (see later):-
"select * from "+ TABLE_NAME + "where" + COL_2 + "=S1"
(+ added after COL_2 and = moved inside the quotes.
However I then believe that this would fail because you have omitted spaces before and after where, so the above would then resolve to:-
select * from tracker_new_tablewhereLINETYPE = S1
With spaces around where as per :-
"select * from "+ TABLE_NAME + " where " + COL_2 + "=S1"
It will then resolve to :-
select * from tracker_new_table where LINETYPE=S1
However, SQLite will then fail as S1 is not numeric and thus must be in quotes, so you need to actually code :-
"select * from "+ TABLE_NAME + " where " + COL_2 + "='S1'"
However coding :-
public Cursor getProgressBar1() {
SQLiteDatabase db = this.getWritableDatabase();
Cursor res = db.query("select * from "+ TABLE_NAME + "where" + COL_2="S1");
return res;
}
Will then fail as the Cursor query method expects at least 7 parameters, as per :-
query(String table, String[] columns, String selection, String[]
selectionArgs, String groupBy, String having, String orderBy)
Query the given table, returning a Cursor over the result set.
SQLiteDatabase
So to use the query method the parameters would be:-
1) The name of the table to be queried so db.query(TABLE_NAME ......
2) A string array of the column names to extract, null means all and equates to *, so db.query(TABLE_NAME,null ......
3) The selection string (SELECT clause) (which can include placeholders i.e ? as per 4th parameter). Without place holders db.query(TABLE_NAME,null,COL_2 + "='S1'", or with a placeholder (generally considered the preferred method), db.query(TABLE_NAME,null,COL_2 + "=?" ......
4) The values to replace the placeholder(s) on a use once basis. So for a single place holder new String[]{"S1"} could be used, so the code now becomes db.query(TABLE_NAME,null,COL_2 + "=?",new String[]{"S1"} ......
5) A GROUP BY clause, null if not using one.
6) A HAVING clause, null if not using one.
7) An ORDER BY clause, null it not using one.
(Note clauses do not have the respective KEYWORDS the query method inserts them it also handles escaping/quoting)
The full query could/should be:-
Cursor res = db.query(TABLE_NAME,null,COL_2 + "=?",new String[]{"S1"},null,null,null);
Finally
And the ProgressBar1 method would be:-
public Cursor getProgressBar1() {
SQLiteDatabase db = this.getWritableDatabase();
Cursor res = db.query(TABLE_NAME,null,COL_2 + "=?",new String[]{"S1"},null,null,null);
return res;
}
Edit after comment
As you want to also search for "S2" and "S3" then perhaps a single method could cope e.g.
public Cursor getProgressBar(String linetype) {
SQLiteDatabase db = this.getWritableDatabase();
Cursor res = db.query(TABLE_NAME,null,COL_2 + "=?",new String[]{linetype},null,null,null);
return res;
}
Then for progress bar 1 you could use:-
Cursor progressbar1 = getProgressbar("S1");
for progress bar 2
Cursor progressbar2 = getProgressbar("S2");
etc
You could also shorten the getProgressBar method to :-
public Cursor getProgressBar(String linetype) {
SQLiteDatabase db = this.getWritableDatabase();
return db.query(TABLE_NAME,null,COL_2 + "=?",new String[]{linetype},null,null,null);
}
or even :-
public Cursor getProgressBar(String linetype) {
return this.getWritableDatabase().query(TABLE_NAME,null,COL_2 + "=?",new String[]{linetype},null,null,null);
}

Just try to modify this query:
Cursor res = db.query("select * from "+ TABLE_NAME + "where" + COL_2="S1");
to:
Cursor res = db.rawQuery("select * from "+ TABLE_NAME + " where " + COL_2 + " = ?", new String[] {"S1"});
and in getProgressBar2() method too. For more info look to https://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html

Related

SQLite delete a row and move all other rows up

This might be impossible but I couldn't seem to find a clear answer. When I delete a row in my database I want the other row's IDs to essentially move up, so if I deleted row 2, then row 3's ID would become 2. Is this possible? I am using AUTOINCREMENT so didn't know if there was almost a reverse of that?
Here is my full SQLite Code.
public class ProfileDatabaseHelper extends SQLiteOpenHelper {
public static final String PROFILE_TABLE = "PROFILE_TABLE";
public static final String PROFILE_ID = "ID";
public static final String PROFILE_IMAGE = "PROFILE_IMAGE";
public static final String RADAR_DATA_ONE = "DATA_ONE";
public static final String RADAR_DATA_TWO = "DATA_TWO";
public static final String RADAR_DATA_THREE = "DATA_THREE";
public static final String RADAR_DATA_FOUR = "DATA_FOUR";
public static final String RADAR_DATA_FIVE = "DATA_FIVE";
public static final String RADAR_DATA_SIX = "DATA_SIX";
public ProfileDatabaseHelper(#Nullable Context context) {
super(context, "profiles.db", null, 1);
}
#Override
public void onCreate(SQLiteDatabase db) {
String createTableStatement = "CREATE TABLE " + PROFILE_TABLE + " (" + PROFILE_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + PROFILE_IMAGE + " TEXT, "
+ RADAR_DATA_ONE + " INT, " + RADAR_DATA_TWO + " INT, " + RADAR_DATA_THREE + " INT, " + RADAR_DATA_FOUR + " INT, " + RADAR_DATA_FIVE
+ " INT, " + RADAR_DATA_SIX + " INT)";
db.execSQL(createTableStatement);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
public boolean updateData(Integer id,String profilePhoto,Integer dataOne, Integer dataTwo, Integer dataThree, Integer dataFour, Integer dataFive, Integer dataSix){
SQLiteDatabase db=this.getWritableDatabase();
ContentValues contentValues=new ContentValues();
contentValues.put(PROFILE_ID,id);
contentValues.put(PROFILE_IMAGE,profilePhoto);
contentValues.put(RADAR_DATA_ONE,dataOne);
contentValues.put(RADAR_DATA_TWO,dataTwo);
contentValues.put(RADAR_DATA_THREE,dataThree);
contentValues.put(RADAR_DATA_FOUR,dataFour);
contentValues.put(RADAR_DATA_FIVE,dataFive);
contentValues.put(RADAR_DATA_SIX,dataSix);
db.update(PROFILE_TABLE,contentValues,"ID = ?",new String[] {id.toString()});
return true;
}
public boolean addOne(ProfileModel profileModel){
SQLiteDatabase db = this.getWritableDatabase();
ContentValues cv = new ContentValues();
cv.put(PROFILE_IMAGE, profileModel.getProfilePhoto());
cv.put(RADAR_DATA_ONE, profileModel.getDataOne());
cv.put(RADAR_DATA_TWO, profileModel.getDataTwo());
cv.put(RADAR_DATA_THREE, profileModel.getDataThree());
cv.put(RADAR_DATA_FOUR, profileModel.getDataFour());
cv.put(RADAR_DATA_FIVE, profileModel.getDataFive());
cv.put(RADAR_DATA_SIX, profileModel.getDataSix());
long insert = db.insert(PROFILE_TABLE, null, cv);
if (insert == -1){
return false;
}
else{
return true;
}
}
public Cursor alldata(){
SQLiteDatabase dataBaseHelper = this.getWritableDatabase();
Cursor cursor = dataBaseHelper.rawQuery("select * from PROFILE_TABLE ", null);
return cursor;
}
public boolean delete(int id) {
SQLiteDatabase db = this.getWritableDatabase();
String queryString = "DELETE FROM " + PROFILE_TABLE + " WHERE " + PROFILE_ID + " = " + id;
//deleting row
Cursor cursor = db.rawQuery(queryString, null);
if(cursor.moveToFirst()){
return true;
}
else {
return false;
}
}
}
I am using AUTOINCREMENT so didn't know if there was almost a reverse of that?
First AUTOINCREMENT doesn't increase the rowid (or alias thereof) value rather it is a constraint (rule) that says that the rowid MUST be greater than any that have ever been allocated (if sqlite_sequence hasn't been modified outside of SQLite's management of the table).
It is using INTEGER PRIMARY KEY that allows a value, typically 1 greater than the highest current rowid value, to be automatically assigned. However, if the value + 1 is greater than the maximum possible value (9223372036854775807) then :-
With AUTOINCREMENT you get an SQLITE_FULL error.
Without AUTOINCREMENT attempts are made to find an unused number.
It is extremely unlikely that (9223372036854775807) will be reached/used.
AUTOINCREMENT is less efficient as it has to record the highest ever assigned rowid and does so by using the sqlite_sequence table. In the SQLite documentation it says :-
The AUTOINCREMENT keyword imposes extra CPU, memory, disk space, and disk I/O overhead and should be avoided if not strictly needed. It is usually not needed.
see SQLite Autoincrement
It is a very bad idea to utilise the rowid or an alias thereof for anything other than it's intended use that is for unique identifying a row from another row such as when forming a relationship, updating or deleting a row.
e.g. what if you sort (ORDER BY) the data by another column or columns other than the ID column? Does the id have any meaning to a user of the App?
However, even though this it NOT recommended, the following would do what you wish :-
private void rationaliseCol1Values() {
ContentValues cv = new ContentValues();
Cursor csr = mDB.query(PROFILE_TABLE,null,null,null,null,null,PROFILE_ID + " ASC");
int rowcount = csr.getCount();
long expected_id = 1;
long current_id;
String where_clause = PROFILE_ID + "=?";
String[] args = new String[1];
while (csr.moveToNext()) {
current_id = csr.getLong(csr.getColumnIndex(PROFILE_ID));
if (current_id != expected_id) {
cv.clear();
cv.put(PROFILE_ID,expected_id);
args[0] = String.valueOf(current_id);
mDB.update(PROFILE_TABLE,cv,where_clause,args);
}
expected_id++;
}
csr.close();
// Now adjust sqlite_sequence
where_clause = "name=?";
args[0] = PROFILE_TABLE;
cv.clear();
cv.put("seq",String.valueOf(rowcount));
mDB.update("sqlite_sequence",cv,where_clause,args);
}
Note the code has been taken from the answer here Android Studio Sqllite autoincrement reset
and has been amended to suit but has not been compiled or run and therefore may contain some errors.

Android SQLite table column not being created or recognized. What am I missing?

I am setting up an sqlite database that will store information about products. When it is time for a new item to be added to the database. I get errors for the first table column saying that no such table column exists, when I'm convinced it should be there. My hinch at the moment is that the problem lies in onCreate(). I'm new to sqlite and working on this for someone else, please excuse me if I've overlooked something elementary.
public class itemDB extends SQLiteOpenHelper {
/**Information*/
private static final int DATABASE_VERSION = 1;
private static final String DATABASE_NAME = "ProductInfoDB";
private static final String TABLE_NAME = "ProductInfo_Table";
public static final String COL_PRODUCTNAME = "ProductName";
public static final String COL_INITIALPRICE = "InitialPrice";
public static final String COL_CURRENTPRICE = "CurrentPrice";
public static final String COL_PRICECHANGE = "PriceChange";
public static final String COL_ITEMWEBPAGE = "ItemWebPage";
/** Constructor */
public itemDB(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
/**Creates the table
* #param db Takes the database and creates a table on it
* */
#Override
public void onCreate(SQLiteDatabase db) {
String table =("CREATE TABLE IF NOT EXISTS " + TABLE_NAME + "( "
+ COL_PRODUCTNAME + " TEXT PRIMARY KEY,"
+ COL_INITIALPRICE + " REAL,"
+ COL_CURRENTPRICE + " REAL,"
+ COL_PRICECHANGE + " REAL,"
+ COL_ITEMWEBPAGE + " TEXT " + ") ");
db.execSQL(table);
}
/**needed for database
* Checks if table exists or not
* */
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
onCreate(db);
}
/** This method adds items to the table of the database
* #param item, takes an item and gets its info, then places it on the table of the database
* */
public void addItem(Item item) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(COL_PRODUCTNAME,item.getName());
contentValues.put(COL_INITIALPRICE,item.getPriceInitial());
contentValues.put(COL_CURRENTPRICE,item.getPriceCurrent());
contentValues.put(COL_PRICECHANGE,item.getPriceChange());
contentValues.put(COL_ITEMWEBPAGE,item.getUrl());
db.insert(TABLE_NAME,null ,contentValues);
db.close();
}
/** Methods aids in updating items on database
* */
public void updateItem(String oldName, Item item){
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(COL_PRODUCTNAME,item.getName());
values.put(COL_INITIALPRICE,item.getPriceInitial());
values.put(COL_CURRENTPRICE,item.getPriceCurrent());
values.put(COL_PRICECHANGE,item.getPriceChange());
values.put(COL_ITEMWEBPAGE,item.getUrl());
db.update(TABLE_NAME, values, COL_PRODUCTNAME + " = ?", new String[]{oldName});
db.close();
}
/** This method returns all the items found on the table of the database,
* recurses the table and returns a list of items
* */
public List<Item> getAllItems() {
List<Item> items = new ArrayList<>();
String selectQuery = "SELECT * FROM " + TABLE_NAME;
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
if(cursor.getCount() > 0) {
if (cursor.moveToFirst()) {
do {
String itemName = cursor.getString(0);
double initialP = cursor.getDouble( 1);
double currentP = cursor.getDouble(2);
double priceC = cursor.getDouble(3);
String itemUrl = cursor.getString(4);
Item holder = new Item(itemName, initialP, currentP, priceC, itemUrl);
items.add(holder);
} while (cursor.moveToNext());
}
}
return items;
}
}
Here are the errors I get
2019-04-19 14:14:55.490 11936-11936/edu.package E/SQLiteLog: (1) table ProductInfo_Table has no column named ProductName
2019-04-19 14:14:55.500 11936-11936/edu.packageE/SQLiteDatabase: Error inserting ProductName=tjastjtjjta PriceChange=0.0 CurrentPrice=1372.0450878788292 InitialPrice=1372.0450878788292 ItemWebPage=tuarhwrqhh
android.database.sqlite.SQLiteException: table ProductInfo_Table has no column named ProductName (code 1): , while compiling: INSERT INTO ProductInfo_Table(ProductName,PriceChange,CurrentPrice,InitialPrice,ItemWebPage) VALUES (?,?,?,?,?)
at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:895)
at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:506)
at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:726)
at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:58)
at android.database.sqlite.SQLiteStatement.<init>(SQLiteStatement.java:31)
at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1580)
at android.database.sqlite.SQLiteDatabase.insert(SQLiteDatabase.java:1453)
at edu.utep.cs.cs4330.homework3.itemDB.addItem(itemDB.java:68)
at edu.utep.cs.cs4330.homework3.MainActivity.addItem(MainActivity.java:262)
at edu.utep.cs.cs4330.homework3.EntryDialog$1.onClick(EntryDialog.java:66)
at com.android.internal.app.AlertController$ButtonHandler.handleMessage(AlertController.java:164)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6313)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:872)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:762)
I don't believe that there is any issue with the code you have supplied.
That is copying your code and using the following in the MainActivity:-
public class MainActivity extends AppCompatActivity {
itemDB ItemDBHlpr;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ItemDBHlpr = new itemDB(this);
Item myItem = new Item("tjastjtjjta",0.0,1372.0450878788292,1372.0450878788292,"tuarhwrqhh");
ItemDBHlpr.addItem(myItem);
List<Item> myItemList = ItemDBHlpr.getAllItems();
for (Item i: myItemList) {
Log.d("ITEMFROMLIST",
"Item Name is " + i.getName() +
"\n\tInitial Price = " + String.valueOf(i.getPriceInitial()) +
"\n\tCurrent Price = " + String.valueOf(i.getPriceCurrent()) +
"\n\tPrice Change = " + String.valueOf(i.getPriceChange()) +
"]n]tURL = " + i.getUrl()
);
}
}
}
Results in the following (as expected) in the log :-
04-20 07:21:16.291 10005-10005/? D/ITEMFROMLIST: Item Name is tjastjtjjta
Initial Price = 0.0
Current Price = 1372.0450878788292
Price Change = 1372.0450878788292]n]tURL = tuarhwrqhh
The Likely Issue
As such the issue is most likely that the App has been run and then changes were made that added the ProductName to the table's definition BUT the database wasn't deleted (achieved by either uninstalling the App, deleting the App's data or in your case increasing the Database Version (drops the table and recreates the table)).
The reason why deleting the database works is that the onCreate method only automatically runs when the database is created.
Increasing the Database Version number results in the onUpgrade method being called. This deletes and then recreates the table.
Another Cause
Should a device being used for development have a working/enabled backup manager and the App's manifest has android:allowBackup="true", then there is the potential that the App's data can be restored thus effectively negating uninstalling the App or clearing the App's data. Changing the manifest to use android:allowBackup="false" can overcome such issues.
In this case, increasing the Database Version will also work as it doesn't rely upon the database being deleted. Rather it works as the onUpgrade method is called, this DROP's the table and the call the onCreate method.
Note this does rely upon the onUpgrade being coded accordingly (in this question it is).
Additional
I'd also suggest a few changes to the getAllItems method (comments explain) to be something like :-
/** This method returns all the items found on the table of the database,
* recurses the table and returns a list of items
* */
public List<Item> getAllItems() {
List<Item> items = new ArrayList<>();
//String selectQuery = "SELECT * FROM " + TABLE_NAME; //<<<<<<<<<< COMMENTED OUT not needed as query method builds the SQL
SQLiteDatabase db = this.getReadableDatabase();
//Cursor cursor = db.rawQuery(selectQuery, null);
// Generally recommended to use the query Convenience method rate than rawQuery
Cursor cursor = db.query(TABLE_NAME,null,null,null,null,null,null);
// No Need to do multiple checks for the same i.e. moveTo will return false if the move cannot be made
// if no rows then moveToNext returns false so loop ended
// if at last row then moveToNext will return false thus loop ended
while (cursor.moveToNext()) {
// Rather than hard coding offsets (which could change over time)
// better to get the offset according to the column name
String itemName = cursor.getString(cursor.getColumnIndex(COL_PRODUCTNAME));
double initialP = cursor.getDouble( cursor.getColumnIndex(COL_INITIALPRICE));
double currentP = cursor.getDouble(cursor.getColumnIndex(COL_CURRENTPRICE));
double priceC = cursor.getDouble(cursor.getColumnIndex(COL_PRICECHANGE));
String itemUrl = cursor.getString(cursor.getColumnIndex(COL_ITEMWEBPAGE));
//Item holder = new Item(itemName, initialP, currentP, priceC, itemUrl); // No need for intermediate Item
items.add(new Item(itemName, initialP, currentP, priceC, itemUrl)); //<<<<<<<<<< CHANGED
}
return items;
}

SQLite table row not deleting when delete button pressed, android

I'm trying to delete a row from a table in SQLite for the first time, I thought I'd followed a tutorial and adapted it to my app but I've messed up the syntax somewhere.
Here is the code from DatabaseHelper.java
public void deleteRow (String subject) {
SQLiteDatabase db = this.getWritableDatabase();
db.execSQL("delete from " + TABLE_NAME +" where " + COL_2 + "=" + subject);
}
And the code that calls it from SubjectActivity.java:
public void onClick(View view) {
if(view.getId()==R.id.deleteSubject) {
Bundle extras = getIntent().getExtras();
String subject = extras.getString("subject");
myDb.deleteRow(subject);
}
}
The row should be deleted when a delete button is pressed in the subject activity, but when I do press the button, the app force closes. What am I missing in the syntax?
This is what your current raw query being passed to SQLite looks like:
delete from TABLE_NAME where COL_2 = some_subject
In other words, you are comparing COL_2 against some_subject, which SQLite will interpret as a column, but not as a string literal. Here is the query you intended to run:
delete from TABLE_NAME where COL_2 = 'some_subject'
The best fix here is to use prepared statements, where the query has a positional parameter (?) for the subject string. The statement will automatically take care of escaping the string on your behalf.
public void deleteRow (String subject) {
SQLiteDatabase db = this.getWritableDatabase();
String sql = "DELETE FROM " + TABLE_NAME + " WHERE " + COL_2 + " = ?";
SQLiteStatement statement = db.compileStatement(sql);
statement.bindString(1, subject);
int numRowsDeleted = statement.executeUpdateDelete();
// you might want to check the number of records which were actually deleted
}
Note that it is not very typical to make the table and column names variable for a given statement. Instead, you would usually see these being hard coded. The reason for this is that it is unlikely that you would want to run the same statement on a different table, or the same table but with different columns.
check below code
public void deleteRow (String subject) {
SQLiteDatabase db = this.getWritableDatabase();
db.delete(TABLE_NAME , COL_2 + "=" + subject, null);
}

Android Java SQLite database: The database does not take 2 String inputs

I am learing to code and made a stopwatch that saves the laptimes in a String and gets the date as a String as well. I want to put those in a SQLite database (so i can later display the date in a listview and open it in another activity that shows all the laptimes.) I've followed some of the codes on the internet and try to put stuff together so I might look over some things in my code. I've commented on the parts I think i understand so you can follow my thinking a bit.
The problem: when i press save the following code is executed and returns the toastmessage: Somehting went wrong.
save.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String dateStamp = getCurrentTimeStamp();
AddData(dataInput, dateStamp);
//DatabaseHelper.deleteAll();
}
}); //save data though AddData method as input the listText
The method AddData is as follows:
public void AddData(String time, String date) {
boolean insertData = DatabaseHelper.addData(time, date);
if (insertData) {
toastMessage(dataInput);
} else {
toastMessage("Something went wrong");
}
}
The boolean method in the DatabaseHelper class is this:
public boolean addData(String times, String date) { //addData that takes a string
SQLiteDatabase db = this.getWritableDatabase(); //database called db and use getWritableDatabase method
ContentValues contentValues = new ContentValues(); //make a new object of ContentValues
contentValues.put(COL_2, times); //put COL_2 and the String in the ContentValues object
contentValues.put(COL_3, date);
long result = db.insert(TABLE_NAME, null, contentValues); //insert contentValues object into the table
//if date as inserted incorrectly it will return -1
if (result == -1) {
db.close();
return false;
} else {
return true;
}
}
It works when i input just 1 variable in addData() but not with 2 that I later implemented. I think it should work. Below I also put the code that is used to make the SQLite Database.
public static final String TABLE_NAME = "stopwatch"; //make a table with name
public static final String COL_1 = "ID"; //make an ID for every colomn
public static final String COL_2 = "times"; //make a 2nd colomn for data
public static final String COL_3= "date";
public DatabaseHelper(Context context) {
super(context, TABLE_NAME, null, 1);
}
#Override
public void onCreate(SQLiteDatabase db) { //make the onCreate method that takes the database as input
String createTable = "CREATE TABLE " + TABLE_NAME + " ( " + COL_1 + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
COL_2 +" TEXT" + COL_3 +" TEXT)"; //create the table with SQL statements to input the data correctly
db.execSQL(createTable); //input the SQL statements in the DB
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { //make upgrade method that takes the database and the versions
db.execSQL("DROP IF TABLE EXISTS " + TABLE_NAME); //execute SQL statements drop table and which one
onCreate(db); //run through create method
}
I hope someone can help me to find the problem so I can learn more.
Your create table query is missing a comma after the COL_2 +" TEXT"
#Override
public void onCreate(SQLiteDatabase db) {
String createTable = "CREATE TABLE " + TABLE_NAME + " ( " + COL_1 + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
COL_2 +" TEXT, " + COL_3 +" TEXT)"; // Added a comma after the COL_2
db.execSQL(createTable);
}
I can see one problem from a quick glance and that is a missing comma in your creation statement which would mean that your database was not created as you intended. Try the below amendment.
String createTable = "CREATE TABLE " + TABLE_NAME + " ( " + COL_1 + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
COL_2 +" TEXT," + COL_3 +" TEXT)";

android.database.sqlite.SQLiteException: table has no such column

So I guess it is a very common issue, searching the web I found that I am not the only one who faced a such issue and yes I know that there is a question with almost the same title, however that did not help to solve the issue I am facing ... so let's start from the beginning
I am simply trying to insert into a table that I created.
This table has three columns: "id", "name", "value", and was created as following
public static final String TABLE_NAME = "cookie";
public static final String COLUMN_ID = "_id";
public static final String COLUMN_NAME = "name";
public static final String COLUMN_VALUE = "val";
private static final String DATABASE_NAME = "commments.db";
private static final int DATABASE_VERSION = 2;
// Database creation sql statement
private static final String DATABASE_CREATE = "create table "
+ TABLE_NAME + "("
+ COLUMN_ID + " integer primary key autoincrement, "
+ COLUMN_VALUE + "text not null, "
+ COLUMN_NAME + " text not null"
+ ");";
public MySQLiteHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase database) {
database.execSQL(DATABASE_CREATE);
}
Now I am trying to insert into this table as following
ContentValues values = new ContentValues();
values.put(MySQLiteHelper.COLUMN_NAME, "username");
values.put(MySQLiteHelper.COLUMN_VALUE, username);
long insertId = database.insert(MySQLiteHelper.TABLE_NAME, null, values);
Cursor cursor = database.query(MySQLiteHelper.TABLE_NAME, allColumns, MySQLiteHelper.COLUMN_ID + " = " + insertId, null, null, null, null);
cursor.moveToFirst();
nameValuePair newComment = cursorToNameValuePair(cursor);
cursor.close();
However I am getting this error
table cookie has no column named val
I searched for similar issues online, most of the solution where talking about a change happened to the database so I need to either
1- Un-install the application before trying to run in debugging mode again
2- update the database version from 1 to 3
However that did not help .. So looking forward for your solutions :)
Problem is here
+ COLUMN_VALUE + "text not null, "
into DATABASE_CREATE String. You missed space between column name and column type.
It should be
+ COLUMN_VALUE + " text not null, "

Categories