Reset the row number count in an android DataBase - java

I need to reset the row number count to 1.
How can I do that?
An example for an update query in my code:
public boolean update (long rowId, String title, String body, String reminderDateTime, String loca, String type, String settime, String lat, String llong) {
ContentValues args = new ContentValues();
args.put(KEY_TITLE, title);
args.put(KEY_BODY, body);
args.put(KEY_DATE_TIME, reminderDateTime);
args.put(KEY_LOCATION, loca);
args.put(KEY_TYPE, type);
args.put(KEY_SETTIME, settime);
args.put(KEY_LAT, lat);
args.put(KEY_LONG, llong);
return mDb.update(DATABASE_TABLE, args, KEY_ROWID + "=" + rowId, null) > 0;
I tried to do that but the eclipse showing me an error:"sqlite_sequence cannot be resolved to a variable"
public void resetAutoNumbering ()
{
mDb.update(sqlite_sequence, args, KEY_ROWID + "=" + rowId, null);
}
What can I do and how?

Found this as answer for a similar question SQLite Reset Primary Key Field:
delete from your_table;
delete from sqlite_sequence where name='your_table';
SQLite Autoincrement
SQLite keeps track of the largest ROWID that a table has ever held using the special SQLITE_SEQUENCE table. The SQLITE_SEQUENCE table is created and initialized automatically whenever a normal table that contains an AUTOINCREMENT column is created. The content of the SQLITE_SEQUENCE table can be modified using ordinary UPDATE, INSERT, and DELETE statements. But making modifications to this table will likely perturb the AUTOINCREMENT key generation algorithm. Make sure you know what you are doing before you undertake such changes.
-axel

You use sqlite_sequence in your procedure but before this you used DATABASE_TABLE instead of sqlite_sequence. Change your sqlite_sequence to DATABASE_TABLE.

Related

sqlite database inserts data in the wrong order sometimes

I'm working with android studio and I need to insert some data into a database. Sometimes, it works, but sometimes, I get this error. I can't really figure out the difference between the times it works and the times it doesn't.
2019-11-09 11:38:34.912 4369-4369/com.example.android.fresh
D/DatabaseHelper: addData: Adding John Smith to people_table
2019-11-09 11:38:34.913 4369-4369/com.example.android.fresh E/SQLiteLog:
(20) statement aborts at 5: [INSERT INTO
people_table(name,amount,contact_no) VALUES (?,?,?)] datatype mismatch
2019-11-09 11:38:34.916 4369-4369/com.example.android.fresh
E/SQLiteDatabase: Error inserting name=John Smith amount=255.0 contact_no= 1234567890 from {P:4369;U:10178}
android.database.sqlite.SQLiteDatatypeMismatchException: datatype mismatch (code 20 SQLITE_MISMATCH)
at android.database.sqlite.SQLiteConnection.nativeExecuteForLastInsertedRowId(Native Method)
at android.database.sqlite.SQLiteConnection.executeForLastInsertedRowId(SQLiteConnection.java:796)
at android.database.sqlite.SQLiteSession.executeForLastInsertedRowId(SQLiteSession.java:788)
at android.database.sqlite.SQLiteStatement.executeInsert(SQLiteStatement.java:86)
at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1613)
at android.database.sqlite.SQLiteDatabase.insert(SQLiteDatabase.java:1482)
at com.example.android.fresh.DatabaseHelper.addData(DatabaseHelper.java:51)
at com.example.android.fresh.createPerson.AddData(createPerson.java:94)
at com.example.android.fresh.createPerson$1.onClick(createPerson.java:58)
at android.view.View.performClick(View.java:6669)
at android.view.View.performClickInternal(View.java:6638)
at android.view.View.access$3100(View.java:789)
at android.view.View$PerformClick.run(View.java:26145)
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:6898)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:537)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
The relevant code in my database helper class is as follows:
private static final String COL1 = "contact_no";
private static final String COL2 = "name";
private static final String COL3 = "amount";
#Override
public void onCreate(SQLiteDatabase db) {
String createTable = "CREATE TABLE " + TABLE_NAME + " (ID INTEGER PRIMARY KEY AUTOINCREMENT,"
+ COL1 + " TEXT NOT NULL," +
COL2 + " TEXT NOT NULL,"
+ COL3 + " REAL)" ;
db.execSQL(createTable);
public boolean addData(String contactNo, String contactName, double amount) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(COL1, contactNo);
contentValues.put(COL2, contactName);
contentValues.put(COL3, amount);
Log.d(TAG, "addData: Adding " + contactName + " to " + TABLE_NAME);
long result = db.insert(TABLE_NAME, null, contentValues);
if (result == -1) {
return false;
} else {
return true;
}
}
This is the code in the createPerson class:
public void AddData(String contactNo, String contactName, double amount) {
boolean insertData = mDatabaseHelper.addData(contactNo, contactName, amount);
if (insertData) {
check =1;
toastMessage("Contact Inserted");
} else {
toastMessage("Something went wrong");
}
}
And this is the method call statement:
AddData(contactNumber, contactName, amount);
Each one of these is in the order contactNumber, contactName, and amount, but the sqlite error i' m getting is inserting it in the order contactName, amount, and contactNumber. I really can't understand how this is happening.
There is only 1 situation where when a data type mismatch will occur, due to SQLite being able to store any type of data in any type of column (with 1 exception and thus the cause/issue).
you wish to have a read of Datatypes In SQLite Version 3, as this explains about the type and how it is flexible in comparison to typically databases. It also explains about rowid's aliases and AUTOINCREMENT.
The exception is for a column that is an alias of the rowid column. An alias of the rowid column is defined by using INTEGER PRIMARY KEY (specifically INTEGER not INT or not any other value that will result in a derived type of INTEGER).
Note that AUTOINCREMENT is can be added to (and only to) the definition, although it is inefficient to do so, and rarely needed.
The rowid and therefore an alias thereof MUST contain an integer value (up to 64 bit signed).
As such you are somehow trying to insert a non-integer value into an alias of the rowid, this cannot be the case if the SQL as shown is used to create the table.
As such the SQL has not been successfully run and created the table, but what is very likely the cause is that a previous table exsists that was created using different SQL.
Simply changing the create SQL will not result in the table being changed. That is because a database persists (stays there) between runs. As such the onCreate method will only be automatically run once for the lifetime of the database.
If you change the schema (the create SQL), then you have to find some way of running the SQL (which would involve dropping the table). The simplest way when developing an App, is to either
delete the App's data,
to uninstall the App or to
increment the version number
this latter option will only work if the onUpgrade drops the table(s) so they can be recreated and invokes the changed SQL (typically by calling onCreate)).
After doing one of the above the App should then be rerun.
Note the above options will all result in current data being lost. If current data needs to be retained then the process is more complicated and will likely involve ALTER statements to rename tables and statements to copy (INSERT) the data from the original table(s) to the new table(s).
#MikeT already answered this correctly in detail, but nevertheless I'm wondering: why not follow architecture design patterns and implement Android Room?
Using Room, you wouldn't have to worry about this kind of "low level" error. It would tell you what is wrong and that is what it's designed for.
Tip: Let Room do the inserting for you and be happy with persistent data

How to Insert a value where not exist in SQLite Android

I want to insert values into my table only when values don't exist in the table.
String CREATETABLE = "CREATE TABLE contacts ( " +
"id INTEGER PRIMARY KEY AUTOINCREMENT, " +
"name TEXT, "+
"phone TEXT )";
Here is my code to create the table, I used UNIQUE(phone), and it doesn't work.
And to add a new contact I am using this code:
ContentValues values = new ContentValues();
values.put("name", contact.getName()); // get title
values.put("phone", contact.getNumero()); // get author
// 3. insert
db.insert("contacts", // table
null, //nullColumnHack
values);
I don't think there is a way of doing that without retrieving the row first. You query the database looking for that particular contact (which you have to specify at least one column to be unique, or any combination of columns to be primary key) otherwise how would you handle two person with the same name?.
So you query and search for the desired person, if you find it, check if the column is null and a) insert if it is, b) ignore if it isn't. If the query doesn't find any person, you cant just insert.
About the unique constraint, its like this:
String CREATETABLE = "CREATE TABLE contacts ( " +
"id INTEGER PRIMARY KEY AUTOINCREMENT, " +
"name TEXT, " +
"phone TEXT UNIQUE)";
In your sample you are using SQLiteDatabase.insert(), try to use SQLiteDatabase.insertWithOnConflict() with one of values CONFLICT_IGNORE, CONFLICT_REPLACE or others.
Also have a look about implementing database as ContentProvider which is much harder to understand but really good to know.

sqlite how to add value on conflict

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)

Android SQLite ordering table columns differently

I'm setting up an SQLite Database and I've got most things set up how I think they're supposed to be. The main error has to with a column not being where it should be. I initialized the database column names in strings like so:
public static final String KEY_ROWID = "_id";
public static final String KEY_SPORT = "given_sport";
public static final String KEY_NAME = "given_name";
public static final String KEY_DATE = "given_date";
public static final String KEY_TIME = "given_time";
public static final String KEY_PERIOD = "given_period";
public static final String KEY_LOCATION = "given_location";
When it was time to create a table with the column names:
db.execSQL("CREATE TABLE " + DATABASE_TABLE + " (" +
KEY_ROWID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
KEY_SPORT + " TEXT NOT NULL, " +
KEY_NAME + " TEXT NOT NULL, " +
KEY_DATE + " TEXT NOT NULL, " +
KEY_TIME + " TEXT NOT NULL, " +
KEY_PERIOD + " TEXT NOT NULL, " +
KEY_LOCATION + "TEXT NOT NULL);"
);
The problem now is that I'm getting the following error:
05-27 04:13:01.448: E/Database(273): android.database.sqlite.SQLiteException: table groupTable has no column named given_location: , while compiling: INSERT INTO groupTable(given_location, given_time, given_date, given_period, given_sport, given_name) VALUES(?, ?, ?, ?, ?, ?);
It seems like the table names are being reordered and that's what is causing the error in insertion. I'm clueless though and I'd really appreciate some help with this.
EDIT: here's the INSERT command
ContentValues cv = new ContentValues();
cv.put(KEY_SPORT, sportInput);
cv.put(KEY_NAME, nameInput);
cv.put(KEY_DATE, dateInput);
cv.put(KEY_TIME, timeInput);
cv.put(KEY_PERIOD, periodInput);
cv.put(KEY_LOCATION, locationInput);
return dbSQL.insert(DATABASE_TABLE, null, cv);
The problem is probably that you've changed the database structure but not the database version. It's a weird issue that I had to spend a lot of time figuring out the first time.
In your DatabaseHelper class there should be a version number, just increment it by one anytime you change any table schema etc.
EDIT
You're missing a space before the "TEXT" in your SQL table creation.
It should be:
...
+ KEY_LOCATION+ " TEXT" ...
once you fix that, increment the version number again.
The order of the table columns will not create "no column" error. If you have added the column to your table after running your app at least once but haven't incremented the database version, this is one way to cause this error.
The order of these columns:
INSERT INTO groupTable(given_location, given_time, given_date, given_period, given_sport, given_name) ...
depends on the order of the columns when you write your INSERT statement, it is not a fixed order based off of the CREATE command.

How can I restart auto increment ID from 1 in an Android SQLite Database

I have an Android SQLite Database and I inserted some rows. After I deleted these rows the ID column continues from the last ID and I would like to restart the counting from 1.
Inside your .db file there's an table called sqlite_sequence
Each row has two columns 'name' which is the name of the table 'seq' a integer indicating the current last value at this table
You can update it to 0
But beware if your table use this id as the unique identifier.
Take a look at this answer: SQLite Reset Primary Key Field
Try:
delete from sqlite_sequence where name='your_table';
If you want to reset every RowId via content provider try this
rowCounter=1;do {
rowId = cursor.getInt(0);
ContentValues values;
values = new ContentValues();
values.put(Table_Health.COLUMN_ID,
rowCounter);
updateData2DB(context, values, rowId);
rowCounter++;
while (cursor.moveToNext());
public static void updateData2DB(Context context, ContentValues values, int rowId) {
Uri uri;
uri = Uri.parseContentProvider.CONTENT_URI_HEALTH + "/" + rowId);
context.getContentResolver().update(uri, values, null, null);
}

Categories