I have a simple table in my database:
CREATE TABLE [InformacjeZDziekanatu] (
[_id] INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
[DataWstawienia] DATE NOT NULL,
[DataModyfikacji] DATE NOT NULL,
[Tresc] VARCHAR2 NOT NULL);
In my application only what I want to do is to get value of DataWstawienia column.
I am using such method:
try {
ResultSet result = stat.executeQuery("select * from InformacjeZDziekanatu order by _id desc limit 5");
int id;
Date dataWst;
Date dataMod;
String tresc;
for(int j = 0 ; j < 5 ; j++) {
result.next();
Object[] lista = new Object[4];
id = result.getInt("_id");
dataWst = result.getDate("DataWstawienia");
dataMod = result.getDate("DataModyfikacji");
tresc = result.getString("Tresc");
lista[0] = id;
lista[1] = dataWst;
lista[2] = dataMod;
lista[3] = tresc;
dane[j] = lista;
}
}
All dates in DataWstawienia column are today's dates but using this method above I get 1970-01-01 date all the time.
What did I do wrong?
SQLIte does not have a DATE data type. Dates need to either be stored as integers (number of seconds since Unix Epoch is common) or as ISO 8601 times (e.g. 2013-10-01T12:12:12). If you say DATE in your SQLite schema you will store values as strings. Your solution of changing the type of dateWst to String acknowledges the fact that you are storing dates as strings and not as an internal date type.
Related
I am trying to do Batch Insert for a table in Informix.
I tried following code to perform Batch Insert for a normal table.
PreparedStatement ps = conn.prepareStatement("insert into tableName (a,b,c,d) values(?,?,?,?)");
ps.addBatch();
int[] n = ps.executeBatch();
System.out.println("Array size : " + n.length); // Output : Array size : 1
And the above code works successfully for normal table.
But when I try to do the same batch insert on time-series table, its not working, neither there is any Exception caught, also the return type int[] of executeBatch() gives me count as zero.
int[] n = ps.executeBatch();
System.out.println("Array size : " + n.length); // Output : Array size : 0
Any idea what am I missing or doing wrong?
One thing to remember is that for Informix, Timeseries looks a lot like a table inside of a table. So when you insert into your base table, you have a column of type "timeseries". The actual timeseries data then goes into that column. This leads to some strange looking SQL as you have to run "UPDATE" statements to "insert" timeseries data since we are basically manipulating that one column in that one row in our base table.
Here is a full example that uses JDBC to setup a basic timeseries table and do batched inserts on a timeseries column. This example presumes you enter the timeseries data every minute and simulates that.
try(Connection c = DriverManager.getConnection("jdbc:informix-sqli://HOST:PORT/DATABASENAME", "username", "password") {
try(Statement s = c.createStatement()) {
//Auto registers timeseries if it does not exist (12.10 or higher versions of the server I believe)
s.execute("INSERT INTO CalendarPatterns VALUES ('patt_1min', '{1 on , 59 off}, second')");
s.execute("INSERT INTO CalendarTable (c_name, c_calendar)" +
" VALUES ('cal_1min', 'startdate(2018-01-01 00:00:00), " +
" pattstart(2018-01-01 00:00:00), pattname(patt_1min)')");
s.execute("CREATE ROW TYPE ts_basic_row(entry_time DATETIME YEAR TO FRACTION(5), value float NOT NULL)");
s.execute("CREATE TABLE tstab1( id integer, sensor timeseries(ts_basic_row))");
s.execute("EXECUTE PROCEDURE TSContainerCreate ('test_container', 'rootdbs','ts_basic_row', 0, 0)");
}
//Insert a row with a timeseries column
//Note the origin date matches the calendar pattern and calendar from above (explaining those is another exercise)
try(PreparedStatement p = c.prepareStatement("INSERT INTO tstab1 VALUES(?, ?)")) {
p.setInt(1, 1);
p.setString(2, "origin(2018-01-01 12:00:00.00000), calendar(cal_1min), container(test_container), threshold(0), irregular, []");
p.execute();
}
//Now we can bulk insert into our timeseries
//There are other mechanisms (setting IFX_USEPUT, using a bulk loader, etc) which could be faster, but this is a good start
Calendar cal = Calendar.getInstance();
Random r = new Random();
try(PreparedStatement p = c.prepareStatement("UPDATE tstab1 SET sensor = PutElem(sensor, ROW(?, ?)::ts_basic_row) WHERE id=?")) {
for(int i = 0; i < 1000; i++) {
p.setDate(1, new java.sql.Date(cal.getTimeInMillis()));
//add a minute to the calendar
cal.add(Calendar.MINUTE, 1);
p.setDouble(2, r.nextDouble()); //your sensor/timeseries value
p.setInt(3, 1); //The row in your base table (matching the id column)
p.addBatch();
}
int [] results = p.executeBatch();
System.out.println(Arrays.toString(results)); // a bunch of '1' values as expected
}
}
So I'm trying to get a basic sql string to work where it will grab the records in the sqlite database based on between dates. However, for some reason, it doesn't work. I just don't understand why.
private void viewTransactionsBetweenDatesTable(){
//Sets the table to view transactions between certain dates
try{
//Get's the dates from startDateChooserTransactions1 and endDateChooserTransactions1
DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
DateFormat df2 = new SimpleDateFormat("MMM dd, yyyy");
Date sdct = startDateChooserTransactions1.getDate();
Date edct = endDateChooserTransactions1.getDate();
String sdcts = df.format(sdct);
String edcts = df.format(edct);
String sdctlabel = df2.format(sdct);
String edctlabel = df2.format(edct);
//Child's ID
String cid = childIDCheck1.getText();
//Grab's the specified data and places that as the table
String sql = "SELECT * FROM ChildrenPayment WHERE ChildID='"+cid+"' AND strftime('%Y-%m-%d', 'Report Transaction Date') BETWEEN '"+sdcts+"' AND '"+edcts+"' ";
pst = conn.prepareStatement(sql);
rs = pst.executeQuery();
//Sets up the table
Info1.setModel(DbUtils.resultSetToTableModel(rs));
TableColumnModel tcm = Info1.getColumnModel();
//tcm.removeColumn(tcm.getColumn(3));
// tcm.removeColumn(tcm.getColumn(3));
// tcm.removeColumn(tcm.getColumn(10));
// tcm.moveColumn(11, 10);
// tcm.removeColum(tcm.getColumn(13));
//Changes modLabel1
modLabel1.setText(firstNameEditClass1.getText() + " " + lastNameEditClass1.getText() + " Between " + sdctlabel + " - " + edctlabel);
}catch(Exception e){
JOptionPane.showMessageDialog(null, e);
}finally{
try{
pst.close();
rs.close();
}catch(Exception e){
JOptionPane.showMessageDialog(null, e);
}
}
}
I am using a jdatechooser so I am sort of forced to use SimpleDateFormat compared to the better DateTimeFormatter. Anyway, I'm formatting it according to YYYY-MM-DD like sqlite likes, but when I run the function, the table does not display anything. I set the days pretty wide (Feb 01, 2018 to Feb 14, 2018) and the date in my database is Feb 07, 2018. I have a few records in the database for it to pull. However, it just doesn't do it. And no error is popping up, so I do not know why it is not working.
Image of the records that I'm trying to place into my jtable
Edit1: Before I forget, I also tried the following SQL string
String sql = "SELECT * FROM ChildrenPayment WHERE ChildID='"+cid+"' AND 'Report Transaction Date' BETWEEN '"+sdcts+"' AND '"+edcts+"' ";
This will not work:
strftime('%Y-%m-%d', 'Report Transaction Date')
because the format specifiers you have provided require that you supply three values, one each for year, month, and day.
If the dates in the database are stored as complete SQLite datetime strings, you will have to use
"... date([Report Transaction Date]) BETWEEN '"+sdcts+"' AND '"+edcts+"' ";
Note square brackets (not single quotes) around column name. This has nothing to do with needing a date/time value, it's because the column name has spaces in it. Any column name with spaces has to be enclosed in double quotes or square brackets. That's why it's a good idea to never use spaces in column names.
If they are, in fact, stored as 'YYYY-MM-DD' strings, then the reason your alternative didn't work is because you single-quoted the column name 'Report Transaction Date', which results in comparing that literal string to the date values.
Hello I have and SLQLite database in which I have table water_logs
CREATE TABLE water_logs(
_id INTEGER PRIMARY KEY AUTOINCREMENT,
amount REAL NOT NULL,
icon INTEGER NOT NULL,
date INTEGER NOT NULL);
I store date in milliseconds.
Calendar cal = Calendar.getInstance();
cal.getTimeInMillis();
My problem is I want to get the day from the my date column using strftime function. The problem is tjat java calendar timestamp is different from SLQLite time stamp
1436859563832 --> result from cal.getTimeInMillis();
1436607407--> SELECT strftime('%s','now')
What I'm actually trying to do is to group records by day. The following SQL query works just fine if value of SELECT strftime('%s','now') is paste in the date column
SELECT SUM(amount), date(`date`) FROM water_logs
GROUP BY date(`date`, 'unixepoch')
Seems to me that you are using 2 different value types.
When you use
Calendar cal = Calendar.getInstance();
long time = cal.getTimeInMillis();
The output value is in Milliseconds, as described here.
While when you use
strftime('%s','now')
The output value is in Seconds, as described here.
So, that might be the cause for the mismatch between the two values.
Of course that the value in seconds might undergo some rounding which might change its value a little.
I will try to provide you the best way to store Dates in SQLite database.
1) Always use integers to store the dates.
2) Use this utility method to store the dates into the database,
public static Long saveDate(Date date) {
if (date != null) {
return date.getTime();
}
return null;
}
Like,
ContentValues values = new ContentValues();
values.put(COLUMN_NAME, saveDate(entity.getDate()));
long id = db.insertOrThrow(TABLE_NAME, null, values);
3) Use this utility method to load date,
public static Date loadDate(Cursor cursor, int index) {
if (cursor.isNull(index)) {
return null;
}
return new Date(cursor.getLong(index));
}
like,
entity.setDate(loadDate(cursor, INDEX));
4) You can also order the data by date using simple ORDER clause,
public static final String QUERY = "SELECT table._id, table.dateCol FROM table ORDER BY table.dateCol DESC";
//...
Cursor cursor = rawQuery(QUERY, null);
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
// Process results
}
Here I am going to get data based on date only but my data continence both date and time here I am using like query to select that data based on date but I am not getting it can any plz exp line it thanks.
String device = "NR09G05635";
String date = "2013-11-29";
java.util.Date temp = new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH).parse(date);
java.sql.Date date1 = new java.sql.Date(temp.getTime());
sql = "select * from gpsdata1 where deviceId=? and dateTime like '" + date1 + "'";
System.out.println("sql" + sql);
ps1 = con.prepareStatement(sql);
ps1.setMaxRows(1);
ps1.setString(1, device);
ps1.execute();
rs = ps1.getResultSet();
-You use the LIKE operator to compare a character, string, or CLOB value to a pattern. Case is significant. LIKE returns the BOOLEAN value TRUE if the patterns match or FALSE if they do not match
Use TO_CHAR to explicitly create a string based on a DATE, using the format you want. Don't rely on implicit conversions.
Select *
From gpsdata1
Where NVL ( TO_CHAR ( dateTime
, 'YYYY-MM-DD HH:MI:SS AM'
)
, ' ' -- One space
) Like '%';
SELECT * FROM gpsdata1
WHERE deviceId=? and CONVERT(VARCHAR(25), dateTime, 126) LIKE '2013-11-19%'
LIKE operator does not work against DATETIME variables, but you can cast the DATETIME to a VARCHAR
I have the following method in my java. For some reason when I try and cast l_month as a Date it says that the object can not be cast. In my sql statement I convert the date to just be the month using the DATE_FORMAT with '%M', so it just returns a list of month names and the number of logins for that month. How can I get that l_month field to become a Date. Ultimately I am changing it to a string so if it could be cast to a string that would be great also but nothing seems to be working.
public List<Logins> getUserLoginsByMonth() {
Session session = getSessionFactory().openSession();
ArrayList<Logins> loginList = null;
try {
String SQL_QUERY = "SELECT l_date as l_month, SUM(logins) as logins FROM (SELECT DATE_FORMAT(login_time, '%M') as l_date, COUNT(DISTINCT users) as logins FROM user_logins WHERE login_time > DATE_SUB(NOW(), INTERVAL 1 YEAR) GROUP BY DATE(login_time)) AS Z GROUP BY(l_month)";
Query query = session.createSQLQuery(SQL_QUERY)
query.addScalar("l_month")
query.addScalar("logins");
List results = query.list();
for(ListIterator iter = results.listIterator(); iter.hasNext() ) {
Objects[] row = (Object[])iter.next();
System.out.println((Date)row[0}]);
System.out.println((BigInteger)row[1]);
}
}
catch(HibernateException e) {
throw new PersistenceDaoException(e);
}
finally {
session.close();
}
}
DATE_FORMAT is
Blockquote Formats the date value according to the format string.
So it's a string not date.