How to delete old rows from sqlite database on android? - android

I have a parameter, where user can choose for which period of time data should be stored.
I read it in days variable. Date and time, when record was added to the database is stored in KEY_DATE_ADDED, it is created like:
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); // sql date format
Date date = new Date();
initialValues.put(KEY_DATE_ADDED, dateFormat.format(date));
Then I do the following:
mDb.delete(DATABASE_TABLE,
"date(now) > date(" + KEY_DATE_ADDED + ",+" + days + " days)",
null);
and it doesn't work. Actual query (where part) looks like:
WHERE date(now) > date(date_added,+10
days)
What is incorrect here? Looks like instead of date_added something else should be here.
I wanted to use SQL data formatting to avoid re-formatting dates several times.
Is there any GUI for Android database to test SQL queries on the actual data?

ok, I should use date('now') > date('date_added','+10 days')

Keep in mind that may also need to periodically use the VACUUM command to actually reduce the size of the database.
http://www.sqlite.org/lang_vacuum.html

Related

Comparing dates in android sqlite database

I'm comparing two dates in android sqlite database
I stored dates in the format
YYYY-MM-DD
Cursor cursor=db.rawQuery("SELECT * FROM "+tableName+" WHERE SALESDATE BETWEEN '2020-1-01' AND '2020-2-01';",null);
It gives result with dates of month 10, 11 and 12 along with the dates between above specified dates.
I would like to know if it is a bug or is there any mistake in my code.
The problem here is that your date literals are in a non standard (and likely incorrect) format. Appreciate that the following inequality holds true:
'2020-10-01' > '2020-1-01' AND '2020-10-01' < '2020-2-01'
This is true because the text 10 is lexicographically larger than just 1, but also less than 2. To avoid this problem, use proper date literals:
String sql = "SELECT * FROM " + tableName + " WHERE SALESDATE BETWEEN '2020-01-01' AND '2020-02-01';"
Cursor cursor = db.rawQuery(sql, null);
Note that SQLite does not actually have a formal date type. Thus, it is very important to always store your dates in SQLite using a proper ISO format.
You should store your Date as long value in database. Simple new Date().getTime() gives you this value and new Date(long value) returns it back. So you can make such queries easy.
But what I can suggest is to:
Export your table to CSV,
Change the date values to a proper SQLite TimeString and
Re-import the CSV after deleting the original table.
Then, you can run a query like:
SELECT * FROM tableName WHERE SALESDATE BETWEEN '2020-01-01 00:00:00' AND '2020-02-01 23:59:59'

SQLite order by Date with format EEE MMM dd HH:mm:ss zzz yyyy

My date is being saved as a string in sqlite in the format "EEE MMM dd HH:mm:ss zzz yyyy". it is quite important that is saved this way.
However, now I need to fetch the saved data from database whilst ordering them by date starting with the newest.
String selectQuery = "SELECT * FROM " + InteractionSchema.TABLE +
" interaction " + " WHERE interaction." +
InteractionSchema.KEY_owner +
" =? ORDER BY datetime(" + InteractionSchema.KEY_date +
") DESC LIMIT 15";
It is not working at all, I tried using all the other SQLite date function but to no avail. I am pretty sure it has to do with the date format. Has anybody dealt with this before? (PS, it is not a duplicate I have already gone through similar questions on stackoverflow)
You should always save dates as UTC timestamps (INTEGER) in SQLite on Android devices. This way you can easily compare and sort them and they use less storage space.
Then nothing prevents you from formatting the date back to its original format using a SimpleDateFormat.
If the timezone is important to preserve (let's say you want the dates to be always formatted according to the timezone of a specific country instead of using the default locale), then you can save the UTC offset in a separate column next to the timestamp.
If you want to show datetime and also want to be able to sort the data without extra processings, you can have two columns TEXT and INTEGER where you can store formatted date in TEXT column and time in mills in INTEGER column and have you data sorted based on INTEGER data. This way you can achieve both things.

CONVERT(varchar, COLNAME, 120) doesn't work in sqlite java

So I'm trying to query all the same dates but this code won't work
SELECT * FROM schedTBL WHERE CONVERT(varchar, DueDateTime, 120) LIKE " + "'%"+ text + "%'"
it returns no such column:varchar
This looks like a SQL statement for SQL Server, not SQLite...
Assuming you are storing dates in field DueDateTime without the hour part, something like this should do:
SELECT * FROM schedTBL WHERE DueDateTime = '2016-09-24'
Or you'll need like if you also have hour values. That depends on how you are actually storing dates/times in your SQLite DB.
Try formatting the date in Java and send it as a parameter to your query.
SQLite doesn't handle dates like SQL Server.
See:
SQLite Date And Time Functions
In SQLite, date values would be formatted with the strftime() function, or for this particular format, with the date() function:
... WHERE date(DueDateTime) LIKE ...
But this works only for supported date formats.
If the values in your database use an unsupported format, your only choice is to convert them, or to try to match the actual string:
... WHERE DueDateTime LIKE ...

Save SQLite TIMESTAMP in the format of MySQL TIMESTAMP, Android

I want to save current TIMESTAMP to a SQLite database in Android.
But it should be in MySQL TIMESTAMP format which is 2014-04-02 20:04:05
How to make it in db.execSQL();
Please help!
Have a look at SQLite date and time functions. You would do something like
strftime(%Y-%m-%d %H:%M:%S, 'now') in your SQL string. This particular format also has a shortcut: datetime('now')
db.execSql("insert into table (column) values ( datetime('now') )");
My preference though is to simply store the current time as a long, which you can then format any way you like (or any way the user likes, or any way the system defaults to showing dates/times).
You should use the following date format in order to insert dates/times in SQLite:
DateFormat dateFormatISO8601 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
and retrieve in string as below:
String crntDate = dateFormatISO8601.format(new Date());
P.S. Make sure your column is of type DATETIME

How insert a date and time in sqlite from the current date and time of the system? [duplicate]

I want to create a table in SQLite in which one of the field is for date, in which date and time of current instance should save. Which data type should I use?
I'm planning to use 'timestamp'. How to insert current timestamp value to the field? Also how to write content values for this date field?
SQLite supports the standard SQL variables CURRENT_DATE, CURRENT_TIME, and CURRENT_TIMESTAMP:
INSERT INTO Date (LastModifiedTime) VALUES(CURRENT_TIMESTAMP)
The default data type for dates/times in SQLite is TEXT.
ContentValues do not allow to use generic SQL expressions, only fixed values, so you have to read the current time in Java:
cv.put("LastModifiedTime",
new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
INSERT INTO Date (LastModifiedTime) VALUES(DateTime('now'))
Use this site for further reference.
To get the current local(system) time, add the 'localtime' option:
select datetime('now', 'localtime');
I'm using timestamps a lot in my app. For me the best way to keep the timestamp is to convert it in milliseconds. After that it is easy to convert it to any locale.
If you need the current time use System.currentTimeMillis().
Content values are easy to use, you just and field and value, like:
ContentValues ins_reminder = new ContentValues();
ins_reminder.put("REMIND_TIMESTAMP", System.currentTimeMillis());
Since SQLite 3.38.0, there is a unixepoch() function that returns UNIX timestamp in integer. Does the same thing as strftime('%s').
References:
release log draft
check-in
In my case i wanted to have a timestamp with fractions of a second.
How to get fractions of a second?
To get a value with fractions of a second the following worked with sqlite and .net-core using ado.net
INSERT INTO YourTable (TimeStamp)
VALUES (strftime('%Y-%m-%d %H:%M:%S:%s'))
CURRENT_TIMESTAMP has only seconds
The built in keyword CURRENT_TIMESTAMP has only a precision of YYYY-MM-DD HH:MM:SS like this
SELECT 'A ' as example, (strftime('%Y-%m-%d %H:%M:%S:%s')) as Better_TimeStamp
, 'With fractions of a seccond' as comment
UNION ALL
SELECT 'B ', CURRENT_TIMESTAMP
, 'only YYYY-MM-DD HH:MM:SS without fractions of a seccond'
This is explained on CREATE the DEFAULT clause
If the default value of a column is CURRENT_TIME, CURRENT_DATE or
CURRENT_TIMESTAMP, then the value used in the new row is a text
representation of the current UTC date and/or time.
The format is
HH:MM:SS for CURRENT_TIME
YYYY-MM-DD for CURRENT_DATE
YYYY-MM-DD HH:MM:SS for CURRENT_TIMESTAMP
Example to use it in c#
The following is based on bulk insert in sqlite with ado.net
public static void InsertBulk(SqliteConnection connection)
{
connection.Open();
using (var transaction = connection.BeginTransaction())
{
var command = connection.CreateCommand();
command.CommandText =
#"INSERT INTO BulkInsertTable (CreatedOn, TimeStamp)
VALUES ($createdOn, strftime('%Y-%m-%d %H:%M:%S:%s'))";
var parameter3 = command.CreateParameter();
parameter3.ParameterName = "$createdOn";
command.Parameters.Add(parameter3);
// Insert a lot of data
// calling System.DateTime.Now outside the loop is faster
var universalTime = System.DateTime.Now.ToUniversalTime();
for (var i = 0; i < 15_000; i++)
{
parameter3.Value = System.DateTime.Now.ToUniversalTime();
// faster
// parameter3.Value = universalTime;
command.ExecuteNonQuery();
}
transaction.Commit();
}
connection.Close();
}

Categories

Resources