I'm using the Google Tasks API in my app. One of the fields in my app "due date" requires a DateTime object. Im using the Android datepicker dailog and an EditText view to capture the due date and then converting the user input into the datetime format. When I try to write to my SQLite database I get the following exception.
Error inserting due=2015-06-14T15:58:38.572-04:00 title=Test app _id=TaskId0.07429873487580996 status=needsAction notes=Test write
android.database.sqlite.SQLiteException: table tasks has no column named due (code 1): , while compiling: INSERT INTO tasks(due,title,_id,status,notes) VALUES (?,?,?,?,?)
which is confusing because I do define a column named "due". Further up in the logs there is another exception.
06-14 15:58:38.607 15395-15395/com.github.idclark.forgetmenot E/EDITFRAGMENT﹕ null
java.text.ParseException: Unparseable date: "06/14/15" (at offset 8)
at java.text.DateFormat.parse(DateFormat.java:579)
at com.github.idclark.forgetmenot.EditFragment.getTaskDueDate(EditFragment.java:64)
The Schema is defined as
public static final class TaskEntry implements BaseColumns {
public static final String TABLE_NAME = "tasks";
public static final String COLUMN_TASK_ID = "_id";
public static final String COLUMN_TASK_TITLE = "title";
public static final String COLUMN_TASK_UPDATED = "updated";
public static final String COLUMN_TASK_SELFLINK = "selfLink";
public static final String COLUMN_TASK_PARENT = "parent";
public static final String COLUMN_TASK_POSITION = "position";
public static final String COLUMN_TASK_NOTES = "notes";
public static final String COLUMN_TASK_STATUS = "status";
public static final String COLUMN_TASK_DUE = "due";
public static final String COLUMN_TASK_COMPLETED = "completed";
public static final String COLUMN_TASK_DELETED = "deleted";
public static final String COLUMN_TASK_HIDDEN = "hidden";
so the "due" column does exist. And the table is created by
#Override
public void onCreate(SQLiteDatabase db) {
//status must be either needsAction or completed
final String CREATE_TASK_TABLE =
"CREATE TABLE " + TaskEntry.TABLE_NAME + " (" +
TaskEntry._ID + " INTEGER PRIMARY KEY," +
TaskEntry.COLUMN_TASK_ID + "TEXT NOT NULL, " +
TaskEntry.COLUMN_TASK_TITLE + "TEXT NOT NULL, " +
TaskEntry.COLUMN_TASK_COMPLETED + "TEXT, " +
TaskEntry.COLUMN_TASK_NOTES + "TEXT, " +
TaskEntry.COLUMN_TASK_STATUS + "TEXT NOT NULL, " +
TaskEntry.COLUMN_TASK_DUE + "DATETIME, " +
TaskEntry.COLUMN_TASK_UPDATED + "DATETIME, " +
TaskEntry.COLUMN_TASK_PARENT + "TEXT, " +
TaskEntry.COLUMN_TASK_DELETED + "BOOLEAN, " +
TaskEntry.COLUMN_TASK_SELFLINK + "TEXT, " +
TaskEntry.COLUMN_TASK_POSITION + "TEXT, " +
TaskEntry.COLUMN_TASK_HIDDEN + "TEXT" + ")";
db.execSQL(CREATE_TASK_TABLE);
}
The due date conversion takes place in this method.
public DateTime getTaskDueDate() {
mDueDate = (EditText) getActivity().findViewById(R.id.task_due_date);
return new DateTime(mDueDate.getText().toString());
}
The data is then finally written to the database with
public boolean insertRow(Task task) {
ContentValues values = new ContentValues();
values.put(TaskContract.TaskEntry.COLUMN_TASK_STATUS, task.getStatus());
values.put(TaskContract.TaskEntry.COLUMN_TASK_ID,task.getId());
values.put(TaskContract.TaskEntry.COLUMN_TASK_TITLE,task.getTitle());
values.put(TaskContract.TaskEntry.COLUMN_TASK_DUE, task.getDue().toString());
values.put(TaskContract.TaskEntry.COLUMN_TASK_NOTES, task.getNotes());
SQLiteDatabase db = this.getWritableDatabase();
boolean createSuccessful = db.insert(TaskContract.TaskEntry.TABLE_NAME, null, values) > 0;
db.close();
return createSuccessful;
}
I'm confused as to why this write fails, and sql claims that there is no "due" column. Even though there is a parse exception, I see a timestamp in the logs as well. Is part of the problem that i'm calling .toString() on the datetime object before writing it to the db? I don't have a lot of sql experience and am genuinely confused as to what to make of these exceptions.
For the sqlite issue, you need to have whitespace between column names and types. For example, change
TaskEntry.COLUMN_TASK_DUE + "DATETIME, " +
to
TaskEntry.COLUMN_TASK_DUE + " DATETIME, " +
There's a similar problem with almost all of your columns.
After fixing the CREATE TABLE SQL, uninstall and reinstall your app to recreate the database.
For the date parsing problem, use a date format that matches your data. If you need detailed help with it, post a new question.
Related
This question already has an answer here:
android.database.sqlite.SQLiteException: no such column or name
(1 answer)
Closed 3 months ago.
I am stuck on an "SQLiteException: no such column:" error. I am trying to make some code to check if an item exists in the database before storing it, I don't know if it's the best way or not but it does the job. Or not really, when I use all numbers for the data in the particular column that I'm searching it works fine. But if there is any letter in the column data it crashes.
The MainActivity
private ConversationsDatabaseHelper db;
//onCreate stuff here
db = new ConversationsDatabaseHelper(this);
String threadId = "886";
Log.d(TAG, "dbTest: EXISTS; " + db.conversationExists(threadId));
and in the databaseHelper class is the converstionExists function
public boolean conversationExists(String threadId) {
// Select All Query
String selectQuery = "SELECT * FROM " + Conversations.TABLE_NAME + " WHERE " +
Conversations.COLUMN_THREAD_ID + " LIKE " + threadId;
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
boolean returnValue = false;
// Check if this message exists
if (cursor.moveToFirst()) {
returnValue = true;
}
// close db connection
db.close();
return returnValue;
}
So if I use for example "886" as the threadId value then all is fine. If I create a row with matching threadId then it returns true. In this case I did not so hence false.
stack trace...
dbTest: EXISTS; false
but using a886 results in
Caused by: android.database.sqlite.SQLiteException: no such column: a886 (code 1 SQLITE_ERROR): , while compiling: SELECT * FROM conversations WHERE thread_id LIKE a886
and 88a6 results in this
Caused by: android.database.sqlite.SQLiteException: unrecognized token: "88a6" (code 1 SQLITE_ERROR): , while compiling: SELECT * FROM conversations WHERE thread_id LIKE 88a6
It almost looks like mixing letters and numbers might be part of the reason here but should not be as the column was created to hold TEXT datatype. here is the database create table query string.
public static final String TABLE_NAME = "conversations";
public static final String COLUMN_ID = "id";
public static final String COLUMN__ID = "_id";
public static final String COLUMN_GROUP_ID = "group_id";
public static final String COLUMN_LAST_MESSAGE_ID = "last_message_id";
public static final String COLUMN_THREAD_ID = "thread_id";
public static final String COLUMN_ADDRESS = "address";
public static final String COLUMN_CONTACT = "contact";
public static final String COLUMN_BODY = "body";
public static final String COLUMN_DATE = "date";
public static final String COLUMN_TYPE = "type";
public static final String COLUMN_STATE = "state";
public static final String COLUMN_READ = "read";
public static final String COLUMN_STATUS = "status";
public static final String COLUMN_CT = "ct";
// Create table SQL query
public static final String CREATE_TABLE =
"CREATE TABLE " + TABLE_NAME + "("
+ COLUMN_ID + " INTEGER PRIMARY KEY ,"
+ COLUMN_LAST_MESSAGE_ID + " TEXT,"
+ COLUMN__ID + " TEXT,"
+ COLUMN_GROUP_ID + " TEXT,"
+ COLUMN_THREAD_ID + " TEXT,"
+ COLUMN_ADDRESS + " TEXT,"
+ COLUMN_CONTACT + " TEXT,"
+ COLUMN_BODY + " TEXT,"
+ COLUMN_DATE + " TEXT,"
+ COLUMN_TYPE + " TEXT,"
+ COLUMN_STATE + " TEXT,"
+ COLUMN_READ + " TEXT,"
+ COLUMN_STATUS + " TEXT,"
+ COLUMN_CT + " TEXT"
+ ")";
I am "up a creek" with this and any help would be greatly appreciated.
The value a886 should be a text/string literal not a numeric literal. Therefore it should be enclosed in single quotes. The errors are because:-
a886 fails with no column found as it's taken to be a column name as it's not a literal.
whilst 88a6 is first not a valid literal (due to the a) and therefore a column name but then an invalid column (cannot start with a numeric unless enclosed) name and thus not a known token.
See Literal Values (Constants)
You could fix this using (enclosing the threadId in single quotes ) :-
String selectQuery = "SELECT * FROM " + Conversations.TABLE_NAME + " WHERE " +
Conversations.COLUMN_THREAD_ID + " LIKE '" + threadId + "'";
However, it is recommended to use bound parameters to protect against SQL Injection.
Thus it would be recommended to use :-
String selectQuery = "SELECT * FROM " + Conversations.TABLE_NAME + " WHERE " +
Conversations.COLUMN_THREAD_ID + " LIKE ?";
along with :-
Cursor cursor = db.rawQuery(selectQuery, new String[]{threadId});
i.e. the ? is replaced by the threadId value properly enclosed.
You may wish to consider using the convenience query method rather than rawQuery, this would be :-
Cursor cursor = db.query(Conversations.TABLE_NAME,null,Conversations.COLUMN_THREAD_ID + " LIKE ?", new String[]{theadId},null,null, null);
The SQL is built for you.
It almost looks like mixing letters and numbers might be part of the reason here but should not be as the column was created to hold TEXT datatype.
SQlite has no issue storing any value in any type. The type, which itself can be virtually anything (rules are used to determine the resultant type), is only an indication of the value that will be stored. The only exception is that a rowid or an alias of the rowid MUST be an integer value (your id column is an alias of the rowid column).
hi i am trying to make a raffle table but however i did created the database but no table is create, the run panel shows that i created it but the sqlite browser shows that there is nothing in it.
here is the code:
in the database java:
public void onCreate(SQLiteDatabase db)
{
// Note the use of super, which calls the constructor of the SQLiteOpenHelper class,
// which does the actual work of opening the database.
Log.d(TAG, "DatabaseHelper onCreate");
Log.d(TAG, RaffleTable.CREATE_STATEMENT);
db.execSQL(RaffleTable.CREATE_STATEMENT);
}
in the raffletalbe.java:
public class RaffleTable {
public static final String TABLE_NAME = "Raffle";
public static final String KEY_ID = "raffle_id";
public static final String KEY_NAME = "raffle_name";
public static final String KEY_PRICE = "price";
public static final String KEY_START = "raffle_start";
public static final String KEY_END = "raffle_end";
public static final String KEY_DESCRIPTION = "raffle_description";
public static final String KEY_TYPE = "raffle_type";
public static final String KEY_PRIZE = "raffle_prize";
public static final String KEY_LIMIT = "raffle_limit";
public static final String CREATE_STATEMENT = "CREATE TABLE "
+ TABLE_NAME
+ " (" + KEY_ID + " integer primary key autoincrement, "
+ KEY_NAME + " string not null, "
+ KEY_DESCRIPTION + " string, "
+ KEY_START + " string not null, "
+ KEY_END + " string not null, "
+ KEY_TYPE + " integer not null, "
+ KEY_LIMIT + " integer, "
+ KEY_PRIZE + " String, "
+ KEY_PRICE + " real);";
what it shows in the run panel:
D/RaffleDatabase: DatabaseHelper onCreate
CREATE TABLE Raffle (raffle_id integer primary key autoincrement, raffle_name string not null, raffle_description string, raffle_start string not null, raffle_end string not null, raffle_type integer not null, raffle_limit integer, raffle_prize String, price real);
here is the code i used to insert the table:
Raffle Ruffle1 = new Raffle();
Ruffle1.setRuffleDes("742 Evergreen Terrace");
Ruffle1.setRuffleEnd("20190102");
Ruffle1.setRuffleStart("20190101");
Ruffle1.setRuffleLimit(5);
Ruffle1.setRuffleName("testing");
Ruffle1.setRufflePrize("cooper");
Ruffle1.setRuffleType("Normal");
Ruffle1.setRufflePrice(1000);
Raffle Ruffle2 = new Raffle();
Ruffle2.setRuffleDes("742 Evergreen Terrace");
Ruffle2.setRuffleEnd("20190102");
Ruffle2.setRuffleStart("20190101");
Ruffle2.setRuffleLimit(5);
Ruffle2.setRuffleName("testing");
Ruffle2.setRufflePrize("cooper");
Ruffle2.setRuffleType("Normal");
Ruffle2.setRufflePrice(1000);
RaffleTable.insert(db, Ruffle1);
RaffleTable.insert(db, Ruffle2);
There is nothing wrong with your code. You just need to put the updated file in your browser. May be your browser is reading the old file that's why you're not able to read the updated content.
I have some string const inside code. Can I put all this into resources strings.xml? I assume that the possibility of separate use of column names will remain. It is necessary to search for the index of posts in future requests to the database. Not to use the indexes the numbers is confusing, uncomfortable.
private static final String NAME_DB = "cars.db";
private static final String TABLE_NAME = "cars";
private static final String COL_BRAND = "brand";
private static final String COL_MODEL = "model";
private static final String COL_COLOR = "color";
private static final String COL_MAX_SPEED = "max_speed";
private static final String COL_ENGINE_POWER = "engine_power";
private static final String CREATE_TABLE =
"CREATE TABLE IF NOT EXISTS " + TABLE_NAME + " (" +
"id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL," +
COL_BRAND + " TEXT NOT NULL, " +
COL_MODEL + " TEXT NOT NULL, " +
COL_COLOR + " TEXT, " +
COL_MAX_SPEED + " INTEGER," +
COL_ENGINE_POWER + " INTEGER)";
private static final String INSERT_DEFAULT_VALUES =
"INSERT INTO " + TABLE_NAME + "(brand, model, color, max_speed, engine_power) VALUES" +
"('Audi', 'Q7 II', 'White', 233, 252)," +
"('Acura', 'ZDX', 'Black', 241, 300)," +
"('BMW', 'X1 I', 'Blue', 205, 204)," +
"('Hyundai', 'Solaris', 'Red', 100, 100)," +
"('Hyundai', 'Tucson', 'Gray', 150, 177)," +
"('BMW', '8 G14', 'Black', 250, 320)";
private static final String SELECT_ALL = "SELECT * FROM " + TABLE_NAME;
private static final String SELECT_TOP_1 = "SELECT * FROM " + TABLE_NAME + " LIMIT 1";
Example code
DatabaseAdapter(Context context) {
db = context.openOrCreateDatabase(NAME_DB, MODE_PRIVATE, null);
db.execSQL(CREATE_TABLE);
Cursor cursor = db.rawQuery(SELECT_TOP_1, null);
if (!cursor.moveToFirst()) {
db.execSQL(INSERT_DEFAULT_VALUES);
}
}
String[] selectAll() {
Cursor cursor = db.rawQuery(SELECT_ALL, null);
if (!cursor.moveToFirst()) {
return null;
}
ArrayList<String> list = new ArrayList<>();
while (cursor.moveToNext()) {
list.add(
cursor.getString(cursor.getColumnIndex(COL_BRAND)) + " " +
cursor.getString(cursor.getColumnIndex(COL_MODEL)) + " " +
cursor.getString(cursor.getColumnIndex(COL_COLOR)) + " " +
cursor.getString(cursor.getColumnIndex(COL_MAX_SPEED)) + " " +
cursor.getString(cursor.getColumnIndex(COL_ENGINE_POWER))
);
}
return list.toArray(new String[0]);
}
There are some solutions with SQL in XML. Look if you can use one of those.
However IMHO it is better to centralize the code and keep text there, without constants even.
Separate concerns: database query and resulting object. This can be done by providing a Stream of a low-level result set object, that using classes can map to their own classes.
Decouples classes; keeps the layers separate. (Maybe less interesting on Android.)
The using code becomes nicely compact, the queries being elsewhere.
My arguments:
Less back and forth jumping to different sources
Better readability
Column names do not change
Capitals of constants are less readable
Keeping the code together prevents similar queries to be spread around unattended
However it still is better than SQL in the higher level business code, to isolate SQL in XML to have smaller source, queries elsewhere. So at least do that.
Java - Storing SQL statements in an external file
I have an android app where I've Created a Database Table named chats with the following Schema
package com.messaging.chatify.Schema;
public class Messages {
public static final String TABLE_MESSAGES = "chats";
public static final String MESSAGE_ID = "_id";
public static final String MESSAGE_TEXT = "text";
public static final String MESSAGE_ATTACHMENT = "attachement";
public static final String MESSAGE_SENDER = "msgfrom";
public static final String MESSAGE_RECEIVER = "msgto";
public static final String MESSAGE_ISREAD = "isRead";
public static final String MESSAGE_TIME = "mtime";
public static final String[] ALL_COLUMNS = { MESSAGE_ID, MESSAGE_TEXT, MESSAGE_ATTACHMENT, MESSAGE_SENDER, MESSAGE_RECEIVER, MESSAGE_ISREAD };
public static final String CREATE_STATEMENT =
"CREATE TABLE IF NOT EXISTS " + TABLE_MESSAGES + "(" +
MESSAGE_ID + " TEXT PRIMARY KEY, " +
MESSAGE_TIME + " TEXT, " +
MESSAGE_TEXT + " TEXT, " +
MESSAGE_ATTACHMENT + " TEXT, " +
MESSAGE_SENDER + " TEXT, " +
MESSAGE_RECEIVER + " TEXT, " +
MESSAGE_ISREAD + " INTEGER" + ");";
public static final String DROP_STATEMENT =
"DROP TABLE IF EXISTS " + TABLE_MESSAGES;
}
but unfortunately when I try to get the column mtime from this table,
I get -1
I've exported the database to my computer and checked it with sqlite browser, the column is created and exists
here are the screen shots of the sqlite browser schema and records
SQLITE BROWSER SCHEMA OUTPUT
SQLITE BROWSER DATA OUTPUT
any suggestion how to get rid of this issue?
I suspect you may have omitted the column in :-
public static final String[] ALL_COLUMNS = { MESSAGE_ID, MESSAGE_TEXT, MESSAGE_ATTACHMENT, MESSAGE_SENDER, MESSAGE_RECEIVER, MESSAGE_ISREAD };
Perhaps changing it to be (i.e. adding MESSAGE_TIME):-
public static final String[] ALL_COLUMNS = { MESSAGE_ID, MESSAGE_TEXT, MESSAGE_ATTACHMENT, MESSAGE_SENDER, MESSAGE_RECEIVER, MESSAGE_ISREAD, MESSAGE_TIME };
will resolve the issue. If not then you need to edit your question to include the query that is resulting in the -1.
Alternatively, you could use :-
public static final String[] ALL_COLUMNS = {"*"};
P.S. for all columns you can use * (e.g. SELECT * FROM mytable) (as used in the alternative solution above) or if using the query method you can use null for all columns as the 2nd paremeter.
I'm having an issue with my app.
What my app does is this : gets some data from a couple of edittexts(3 per row,created dynamically) and puts them in a database .
What i want the database to do is this : take the product name,the quantity and the price and put them in the table.The name should be UNIQUE(it will be used to power an autocomplete,it needs to be unique not to have duplicates in the AC list).The price in the database must be the last price inserted for that product(for example,if Cheese at 3$ is inserted and after that Cheese at 2.5$ in the database we will find 2.5$).The quantity has to be summed up(if i enter Cheese in quantity 3 and then again Cheese in quantity 4 in the database we will find 7).
Now,my issue : Lets say i enter this in my shopping list :
1. Hhhh 4 2.5
2. Dddd 3 1
3. Eeee 2 2
4. Aaaa 5 3.5
In my database I will find this :
4. Aaaa 4 2.5
2. Dddd 3 1
3. Eeee 2 2
1. Hhhh 5 3.5
So,the issue is that it arranges the product name column alphabetically but the other columns remain in the same order,the one i entered in the edittexts.
I did some tests,if i remove the UNIQUE from the product name column,it will enter it as it should but of course,it will create duplicates,which i don't need.I don't get it,what's wrong ? why does UNIQUE trigger this ?
Here's my code :
My table creation :
public class SQLiteCountryAssistant extends SQLiteOpenHelper {
private static final String DB_NAME = "usingsqlite.db";
private static final int DB_VERSION_NUMBER = 1;
private static final String DB_TABLE_NAME = "countries";
private static final String DB_COLUMN_1_NAME = "country_name";
private static final String DB_COLUMN_2_NAME = "country_counter";
private static final String DB_COLUMN_3_NAME = "country_price";
private static final String DB_CREATE_SCRIPT = "create table "
+ DB_TABLE_NAME
+ " (_id INTEGER PRIMARY KEY,country_name text unique, country_quantity REAL DEFAULT '0',country_price REAL);) ";
private SQLiteDatabase sqliteDBInstance = null;
public SQLiteCountryAssistant(Context context) {
super(context, DB_NAME, null, DB_VERSION_NUMBER);
}
#Override
public void onCreate(SQLiteDatabase sqliteDBInstance) {
Log.i("onCreate", "Creating the database...");
sqliteDBInstance.execSQL(DB_CREATE_SCRIPT);
}
My insert method :
public void insertCountry(String countryName, String countryPrice,
String countryQuantity) {
sqliteDBInstance.execSQL("INSERT OR IGNORE INTO " + DB_TABLE_NAME
+ "(country_name, country_quantity, country_price) VALUES('"
+ countryName + "','0', '" + countryPrice + "')");
sqliteDBInstance.execSQL("UPDATE " + DB_TABLE_NAME
+ " SET country_name='" + countryName
+ "', country_quantity=country_quantity+'" + countryQuantity
+ "' WHERE country_name='" + countryName + "';");
sqliteDBInstance.execSQL("UPDATE " + DB_TABLE_NAME
+ " SET country_name='" + countryName + "', country_price='"
+ countryPrice + "' WHERE country_name='" + countryName + "';");
}
And this is how i call the insert method :
for (int g = 0; g < allcant.size() - 1; g++) {
if (prod[g] != "0.0") {
sqlliteCountryAssistant.insertCountry(prod[g],pret[g],cant[g]);
}
Also,please excuse my messy code,i've started learning android with no programming background like a month ago.I just got my bachelors degree in Sociology so yea,i'm an absolute beginner.If there is way to do it better then i did and i'm pretty sure there is,please,show me the way,heh.
Thanks and have a good day !
EDIT : Aaaand the whole db class :
public class SQLiteCountryAssistant extends SQLiteOpenHelper {
private static final String DB_NAME = "usingsqlite.db";
private static final int DB_VERSION_NUMBER = 1;
private static final String DB_TABLE_NAME = "countries";
private static final String DB_COLUMN_1_NAME = "country_name";
private static final String DB_COLUMN_2_NAME = "country_counter";
private static final String DB_COLUMN_3_NAME = "country_price";
private static final String DB_CREATE_SCRIPT = "create table "
+ DB_TABLE_NAME
+ " ( id INTEGER PRIMARY KEY AUTOINCREMENT,country_name text unique, country_quantity REAL DEFAULT '0',country_price REAL)";
private SQLiteDatabase sqliteDBInstance = null;
public SQLiteCountryAssistant(Context context) {
super(context, DB_NAME, null, DB_VERSION_NUMBER);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO: Implement onUpgrade
}
#Override
public void onCreate(SQLiteDatabase sqliteDBInstance) {
Log.i("onCreate", "Creating the database...");
sqliteDBInstance.execSQL(DB_CREATE_SCRIPT);
}
public void openDB() throws SQLException {
Log.i("openDB", "Checking sqliteDBInstance...");
if (this.sqliteDBInstance == null) {
Log.i("openDB", "Creating sqliteDBInstance...");
this.sqliteDBInstance = this.getWritableDatabase();
}
}
public void closeDB() {
if (this.sqliteDBInstance != null) {
if (this.sqliteDBInstance.isOpen())
this.sqliteDBInstance.close();
}
}
public void insertCountry(String countryName, String countryPrice,
String countryQuantity) {
ContentValues cv = new ContentValues();
cv.put("country_name", countryName);
cv.put("country_price", countryPrice);
sqliteDBInstance.insertWithOnConflict(DB_TABLE_NAME, null, cv, sqliteDBInstance.CONFLICT_IGNORE);
// Increment the quantity field (there isn't a good way to do this with sql.update() )
sqliteDBInstance.execSQL("UPDATE " + DB_TABLE_NAME + " SET country_quantity=country_quantity+? WHERE country_name=?",
new Object[] { new Long(countryQuantity), countryName });
/*sqliteDBInstance.execSQL("INSERT OR IGNORE INTO " + DB_TABLE_NAME
+ "(country_name) VALUES('" + countryName + "')");
sqliteDBInstance.execSQL("UPDATE " + DB_TABLE_NAME
+ " SET country_quantity=country_quantity+" + countryQuantity
+ " WHERE country_name='" + countryName + "';");
sqliteDBInstance.execSQL("UPDATE " + DB_TABLE_NAME
+ " SET country_price=" + countryPrice
+ " WHERE country_name='" + countryName + "';");*/
}
public boolean removeCountry(String countryName) {
int result = this.sqliteDBInstance.delete(DB_TABLE_NAME,
"country_name='" + countryName + "'", null);
if (result > 0)
return true;
else
return false;
}
public long updateCountry(String oldCountryName, String newCountryName) {
ContentValues contentValues = new ContentValues();
contentValues.put(DB_COLUMN_1_NAME, newCountryName);
return this.sqliteDBInstance.update(DB_TABLE_NAME, contentValues,
"country_name='" + oldCountryName + "'", null);
}
public String[] getAllCountries() {
Cursor cursor = this.sqliteDBInstance.query(DB_TABLE_NAME,
new String[] { DB_COLUMN_1_NAME }, null, null, null, null,
DB_COLUMN_1_NAME + " ASC");
if (cursor.getCount() > 0) {
String[] str = new String[cursor.getCount()];
// String[] strpri = new String[cursor.getCount()];
int i = 0;
while (cursor.moveToNext()) {
str[i] = cursor.getString(cursor
.getColumnIndex(DB_COLUMN_1_NAME));
// strpri[i] = cursor.getString(cursor
// .getColumnIndex(DB_COLUMN_2_NAME));
i++;
}
return str;
} else {
return new String[] {};
}
}
}
I haven't figured out the crazy order but I found two things that might even clear something up:
your create table sql has one closing bracket too much (remove the one after the semicolon)
your insert method is really messy :) I would split it into two methods.
The general approach would be to create an insertOrUpdate method that queries the database for the entry (in your case the countryName). If an entry exist, it will be updated, if not it will be inserted. As you are a beginner, this might be a good task to do that by yourself, you should get the basic code here on SO in different questions.
The final tip (you might have seen it already): Use the parameter version and/or the real update/insert methods from the database.
db.insert(TABLE_NAME, null, contentValues); // see class ContentValues for details
According to the execSQL() method, you shouldn't use that for any SELECT/INSERT/UPDATE/DELETE statement:
Execute a single SQL statement that is NOT a SELECT/INSERT/UPDATE/DELETE.
Now my question which answer might help me to help you:
I would also like to know how you verified the order of your database content? Have you created a query in your android code where you query the content or have you opened the db file with a SQLite manager tool? If you query, can you include your query/display code in your question, too?
A couple of things to add to #WarrenFaith's excellent suggestions. I agree that the error is probably in code you haven't shown.
The quotes around the increment value in the UPDATE SQL are wrong. Should be e.g. quantity=quantity+42, not quantity=quantity+'42'
You need to use argument escapes (question marks ?) to avoid problems including SQL insertion attacks on your app.
The insert logic is insanely complicated. Perhaps this is where the problem lies.
You want something like:
// Insert or ignore.
ContentValues cv = new ContentValues();
cv.put("country_name", country_name);
cv.put("country_price", country_price);
sql.insertWithOnConflict(DB_TABLE_NAME, null, cv, CONFLICT_IGNORE);
// Increment the quantity field (there isn't a good way to do this with sql.update() )
sql.execSQL("UPDATE " + DB_TABLE_NAME + " SET country_quantity=country_quantity+? WHERE country_name=?",
new Object[] { new Long(country_quantity), country_name });
AND you didn't mention if the LogCat is clean. It must be showing DB errors at least regarding the quotes problem. Also suggest you make sure the table is dropped and rebuilt between debugging runs.