So i have this app I'm making for my school project. it has a custom listview with a custom arrayadapter and it's populated by clicking a button. here is the Room class
public class Room {
private int xBtn;
private int _id;
private int roomImage;
private String name;
private String type;
public Room(String name, String type, int roomImage){
this.name = name;
this.type = type;
this.roomImage = roomImage;
}
here is my DBHandling onCreate(), addRoom() and deleteRoom() Methods:
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("DROP TABLE IF EXISTS "+TABLE_NAME);
String query = "CREATE TABLE " + TABLE_NAME + "(" +
COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
COLUMN_NAME + " TEXT, " +
COLUMN_TYPE + " TEXT " +
");";
db.execSQL(query);
}
public void addRoom(Room room){
ContentValues values = new ContentValues();
values.put(COLUMN_NAME, room.getName());
values.put(COLUMN_TYPE, room.getType());
SQLiteDatabase db = getWritableDatabase();
db.insert(TABLE_NAME, null, values);
db.close();
}
public void removeRoom(String roomsName){
SQLiteDatabase db = getWritableDatabase();
db.execSQL("DELETE FROM " + TABLE_NAME + " WHERE " + COLUMN_NAME + "=\"" + roomsName + "\";");
}
My questing is, let say, we have 5 rooms, room1(id=0), room2(id=1) and so on.
and i delete room room3(#2) will the new order become 0,1,3,4 or 0,1,2,3.
if it didn't become 0,1,2,3 , how can i make it work? and if it did become 0,1,2,3 , will the _id in Room itself change as well or will it only be changed in the table? In short, i want the _id in the class Room to adjust itself automatically with the id in the table. how do i make this work?
When you have a primary key auto increment the first entry will be at 0 then 1 them 2 so on on if you update say row at id 1 it stays 1. Now let's say row row gets deleted, but uh oh you need out back in. It will bout be 2 or 3 or wherever is after your last id.
Related
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.
My app works (generate a code and a relative barcode from some user's data in input), but I wanted to store data in a Db with sqlite. This is my DatabaseOpenHelper class:
public class DatabaseOpenHelper extends SQLiteOpenHelper {
public static final String DATABASE_NAME = "cf_db.db";
public static final String TABLE_NAME = "cf_table";
public static final String CF = "CF";
public static final String COL1 = "Name";
public static final String COL2 = "Surname";
public static final String COL3 = "Sex";
public static final String COL4 = "Birthday";
public static final String COL5 = "PlaceOfBirth";
public DatabaseOpenHelper(Context context) {
super(context, DATABASE_NAME, null, 1);
//SQLiteDatabase sqLiteDatabase = this.getWritableDatabase();
}
#Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {
sqLiteDatabase.execSQL("CREATE TABLE " + TABLE_NAME +
"(" + CF + "TEXT PRIMARY KEY, " + COL1 + "TEXT NOT NULL, " +
COL2 + "TEXT NOT NULL," + COL3 + "TEXT NOT NULL," + COL4 +
"TEXT NOT NULL," + COL5 + "TEXT NOT NULL);");
}
#Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
sqLiteDatabase.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
onCreate(sqLiteDatabase);
}
public boolean insertData(String cf, String name, String surname, String sex, String year,
String month, String day, String place) {
String date = day + "/" + month + "/" + year;
SQLiteDatabase sqLiteDatabase = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(CF, cf);
contentValues.put(COL1, name);
contentValues.put(COL2, surname);
contentValues.put(COL3, sex);
contentValues.put(COL4, date);
contentValues.put(COL5, place);
sqLiteDatabase.insert(TABLE_NAME, null, contentValues);
sqLiteDatabase.close();
}
}
There is something wrong with the insert statement at the end. I got below error:
E/SQLiteLog: (1) table cf_table has no column named Birthday
E/SQLiteDatabase: Error inserting Birthday=22/08/21 CF=GGUTUU21M22I754G Surname= ggu Name=uut Sex=M PlaceOfBirth=Siracusa
android.database.sqlite.SQLiteException: table cf_table has no column named Birthday (code 1 SQLITE_ERROR): , while compiling: INSERT INTO cf_table(Birthday,CF,Surname,Name,Sex,PlaceOfBirth) VALUES (?,?,?,?,?,?)
at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:901)
at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:512)
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.insertWithOnConflict(SQLiteDatabase.java:1562)
at android.database.sqlite.SQLiteDatabase.insert(SQLiteDatabase.java:1433)
at com.example.valerio.androidcodesgenerator.DatabaseOpenHelper.insertData(DatabaseOpenHelper.java:53)
at com.example.valerio.androidcodesgenerator.MainActivity.AddData(MainActivity.java:136)
at com.example.valerio.androidcodesgenerator.MainActivity$1.onClick(MainActivity.java:98)
at android.view.View.performClick(View.java:6597)
at android.view.View.performClickInternal(View.java:6574)
at android.view.View.access$3100(View.java:778)
at android.view.View$PerformClick.run(View.java:25883)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6642)
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)
The columns are in a random order that I don't understand, and when I used some print statement to analyze the issue I realized that the various contentValues has no value at all. I just did
Log.d("code", contentValues.getAsString(cf))
And the error was like "println needs something to print", so basically the put statement of the contentValues doesn't put anything in. In fact in the error message the values are (??????)...
In the call instead the print tests goes well and the various editText and textView have their proper content.
This is the insertData call:
public void AddData() {
boolean inserted = myDb.insertData(textView_cf.getText().toString(),
editText_name.getText().toString(),
editText_surname.getText().toString(),
editText_sex.getText().toString(),
editText_aa.getText().toString(),
editText_mm.getText().toString(),
editText_gg.getText().toString(),
autoCompleteTextView_place.getText().toString());
}
(I also need a boolean control over the insertion, but the insertion just doesn't happen right now)
Maybe it's newbie errors but I'm just new at Android Studio and not a Java expert at all...
One thing you must do is uninstall the app from the emulator/device where you test it and then run it again to recreate the database. If it still shows the error about the Birthday field then the problem is somewhere else.
Use this insert method:
public boolean insertData(String cf, String name, String surname, String sex, String year,
String month, String day, String place) {
String date = day + "/" + month + "/" + year;
SQLiteDatabase sqLiteDatabase = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(CF, cf);
contentValues.put(COL1, name);
contentValues.put(COL2, surname);
contentValues.put(COL3, sex);
contentValues.put(COL4, date);
contentValues.put(COL5, place);
int id = sqLiteDatabase.insert(TABLE_NAME, null, contentValues);
sqLiteDatabase.close();
return (id != -1);
}
I'm not sure that this will solve the problem, but by the signature of the method it must return boolean.
You are missing spaces in your CREATE TABLE statement
sqLiteDatabase.execSQL("CREATE TABLE " + TABLE_NAME + "(" +
CF + " TEXT PRIMARY KEY, " +
COL1 + " TEXT NOT NULL, " +
COL2 + " TEXT NOT NULL, " +
COL3 + " TEXT NOT NULL, " +
COL4 + " TEXT NOT NULL, " +
COL5 + " TEXT NOT NULL)");
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)";
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.
I have a database with product name,product price and product counter.
Product name is unique,product price gets replaced everytime a new value is entered and the problem is the product counter.
Its default value is 1,when a new product is entered his value is set to 1.I need it to increment whenever there is a conflict for the product name.So if Cheese is entered twice,the counter will say 2 and so on.
What i need it to do is when there is a conflict,add 1 to its value. I want to do it this way because i'll need this later.I'll need to add the inputed value to the table value on some other thing i plan to implement in my app.
How can i achieve this ? I'd like to keep doing it the way i'm doing it now,with the contentvalues method of inserting and not with the sqlite syntax(INSERT,SELECT,etc).Is that even possible ? Cuz i'm an absolute 0 at sqlite syntax.And also,i need it to have a method that i can call in other activities to insert into the database (like insertCountry(Japan,10))
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_price";
private static final String DB_COLUMN_3_NAME = "country_counter";
private static final String DB_CREATE_SCRIPT = "create table "
+ DB_TABLE_NAME
+ " (_id integer primary key autoincrement, country_name text UNIQUE ON CONFLICT REPLACE,country_price text,country_counter integer default '1' );)";
And this is how i insert :
public void insertCountry(String countryName, String countryPrice) {
sqliteDBInstance.execSQL("INSERT INTO " + DB_TABLE_NAME
+ "(country_name, country_price) VALUES('" + countryName
+ "', '" + countryPrice + "')");
}
Incrementing a value to a specific cell is not available in sqlite. You have to read the current value of cell and add your needed value to it and replace it with the old one. You can use update method.
public void update(String countryName, String price, long id) {
ContentValues cv = new ContentValues();
cv.put(dbHelper.COLUMN_1, countryName); // These Fields should be your
// String values of actual column
// names
cv.put(dbHelper.COLUMN_2, price);
database.update(dbHelper.TABLE_NAME, cv, "_id " + "=" + id, null);
}
every time you're going to add a row to your table you have to read all it and check if the row exists.here is a method to retrieve all rows:
public List<TableRow> getAllRows() {
List<TableRow> rows= new ArrayList<TableRow>();
Cursor cursor = database.query(Helper.TABLE_SITUPS, allColumns,
null, null, null, null, null);
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
TableRow row = cursorToRow(cursor);
comments.add(row);
cursor.moveToNext();
}
// Make sure to close the cursor
cursor.close();
return rows;
}
TableRow is a class for database table rows and contains fields stands for actual table columns.
with iterating this list and get "country" value of each one you can understand if that row exists or not.
These are basic concepts of sqlite databases programming. I recommend you to research a bit in this matter.
I don't know your database class, but check this method:
return this.sqliteDBInstance.insertWithOnConflict(DB_TABLE_NAME, null, contentValues, SQLiteDatabase.CONFLICT_REPLACE);
If you are creating your column correctly, if there is a conflict, the new entry will replace the old one.
EDIT: after your last comment, all you need is an update: first query your database with the name of your item (check carefully if parameters are ok):
return this.sqliteDBInstance.query(DB_TABLE_NAME, null, DB_COLUMN_1_NAME + "=?", new String[] {productName}, null, null, null);
This will return a Cursor with 0 or 1 row. If there aren't row, you can proceed inserting data normally (don't forget to add your counter: is 1 on first insert):
public void insertCountry(String countryName, String countryPrice) {
sqliteDBInstance.execSQL("INSERT INTO " + DB_TABLE_NAME
+ "(country_name, country_price) VALUES('" + countryName
+ "', '" + countryPrice + "', '" + countryCounter + "')");
}
if there is 1 row, your product is already on your database, so just iterate the Cursor, take the value on counter, add +1 on it and update your database with this method:
public int update (String table, ContentValues values, String whereClause, String[] whereArgs)