Using Hibernate's Restrictions.ilike() on a Timestamp - java

I've been thinking it over, and I'm starting to wonder if this is even possible.
User Perspective:
There's a table of data, and one column contains a date. The user can type in a search term like dec and get all rows that occurred during December.
Backend: A jqGrid is used for displaying the table. It sends the entered search terms to the server. The server uses the code
Criteria cr = session.createCriteria( DetailedLogEntry.class );
Disjunction disjunction = Restrictions.disjunction();
MatchMode matchMode = MatchMode.ANYWHERE;
disjunction.add( Restrictions.ilike( searchKey.getField(), searchKey.getData(), matchMode ) );
cr.add( disjunction );
to apply the search terms, and where DetailedLogEntry contains a Date variable to represent the database's TIMESTAMPfield.
Because searchKey.getData() returns a string, comparing it against a date object results in an empty set.
So I guess the question is...is it possible, preferbly through Hibernate, to apply a restriction against a Date object as if it were a String?

That's not possible. You'd need to use Restrictions.between() and give it an upper and lower date values. You could use SimpleDateFormat to convert from your String values to Date values and then perform the search?
If the user searched for Dec, would you expect all the log entries from December of every year to show up? Can they type in :"1, Dec" and expect to see all the logs from the 1st December for every year? If it is string matching on dates you are looking for, it might be easier to load all the data into your jqGrid and use javascript to filter the table based on the string formatted date values.

Related

query all the rows with same string(but partial strings was given)

I want to show a query where colname - DueDateTime can be verified either date or time (its datatype is VARCHAR only & its content is date & time values separated with a white space)
Using a WHERE condition if any of the value is true, because I have many rows with same date but different time, I want to show all with the same dates.
`SELECT * FROM NAME_TBL WHERE DueDate = ?`
My information is specific but the question is misleading so I changed the question title.
M.Waqas Pervez has the right answer but it should be %'yourDate'%
you can use groupby clause on DueDate.
try below query.
SELECT * FROM NAME_TBL WHERE Convert(Date,DueDate) = '2016-11-25'

ofy() appengine Date search query

I want to search a list of employee between two dates ie. 1 jan 2014 to 31 Dec 2014 using GAE ofy(objectify) for a branch.How do I do that?
ulist=ofy().load().type(Employee.class).filter("branch", branch).filter("date >=", fromdate).filter("date <=", toDate).list();
There are 2 fields
-Branch is auto generated field.
-For date I have taken 2 Datebox, fromDate and toDate and using those 2 date I have to query on date field.
Above query written is not working & not giving results when searched between date. However if same date is entered in both from date & todate then its working.
Is there any isssue with my logic or is there any other method which I can use to find out employees of branch joined between two dates?
You will need to specify a custom index to support this query as it combines multiple filters on different properties.
As per the documentation:
Other forms of query require their indexes to be specified in the index configuration file, including:
...
Queries with one or more inequality filters on a property and one or more equality filters on other properties
...
Your query has an equality filter (on branch) with two inequality (on date) filters.
The documentation tells you all you need to know about configuring your custom indexes.

Android/java Sqlite: How to retrieve max datetime?

Below is the snapshot of what I have got as a query from sqlite db.
After googling and reading a number of question around, I have come to know that to retrieve maximum datetime using aggregate functions like max() is not possible as sqlite doesn't support much datatypes but treats datatype as text.
So, I have brought this data in a List or at java level. So how could I now get the maximum datetime from this list.
Is there any direct construct for this format in java. Or do we have something at sqlite level that I coudn't find.
texts can be compared, sorted and ordered in SQLite.
Your format appears to be YYYY-MM-dd hh:mm:ss. Lucky for you, ordering this format result in ordering by date.
just
select current_test_id from someTable order by test_datetime desc limit 1
or
select current_test_id, max(test_datetime) from someTable
(or something, not entirely sure for the second one)
if you set the type of datetime field text then you can perform following query
but datetime must be yyyy-mm-dd hh:mm:ss
select max(datetime) from tableName;
A common approach is to store the data converted as long.
Use date.getTime() to get long from your Date instance and Date date = new Date(timestamp); to get a date object from your timestamp.
Once you have a long in your db you can perform any ordering / comparison you want.
To retrive max value from a set of Time of type (String) We have to do some concatenations using sub string .Using this Query max or min Time can be find out using sql lite
select max(datetime(case
when substr(TimeIn,7,2)='PM'
then substr(TimeIn,1,2)+12
else substr(TimeIn,1,2)
end || ':' || substr(TimeIn,4,2) || ':' || '00'))
from tablename
where Date='10/06/2016'

How to perform 'between' in Arabic (hijri) calendar and save it as 'date' in MySQL?

My question is actually my ultimate aim.
So far, I am having 2 issues.
How to save arabic date as a 'date' in mysql?
because, I have been converting Gregorian to Hijri and then, using preg_replace (php, for now, final is in Java) would change the numbers to arabic ascii hex... and then, save it in MySQL as varchar.
I know about collation cp1256_general_ci which allows us to store in arabic but, currently, for simplicity sake, I have put it aside. utf-8_general is doing fine too. So storing as varchar is not an issue, storing as 'date' is.
Performing queries on it.
I thought the requirements would end there but, now the task is to perform queries like date 'between' xyz and pqr... Also, the constraint is to 'store it in arabic only'.
Any inputs are much appreciated.
SQL dates
I'd think about it like this: the server actually stores a date as a reference to a given day. How it does that is no concern of yours. When storing data to or reading data from such a date column, the server represents that date using a specific calendar, which is gregorian by convention. What I'm trying to say is, I wouldn't consider the stored value to be gregorian, although it may well be. I would rather consider the transferred date to be gregorian.
So the best solution, in my opinion, is accepting that fact and converting between Gregorian and Hijri on the application side. That way, you could use normal between checks on that.
Strings made up from numbers
If this is not possible, due to the fact that the locale-dependent conversion is too complicated, or because the mapping betwen Hijri and Grogorian is not unique or not known in advance, then you will have to store the date in some other form. Possible forms that come to my mind are either a varchar containing strings of the form YYYY-MM-DD, with the letters signifying digits. This scheme ensures that strings would compare like the dates they represent, so you could still use between on them. Turning these strings back into spelled out dates would still be tricky, though.
One or more numeric columns
So I would actually suggest you use three columns., each containing a number signifying a date, You could then use 10000*year + 100*month + day_of_month to obtain a single number for each day, which you could use for comparisons and between. On the other hand, you could use the function ELT in your queries to turn the number for the month back into a name. If performance is an issue, you might be better of storing just a single number, and splitting it into parts upon selection. In a Gregorian calendar, this would look like this:
CREATE TABLE tableName (myDate DECIMAL(8));
SELECT myDate DIV 10000 AS year,
ELT((myDate DIV 100) MOD 100, "Jan", "Feb", …) AS month,
myDate MOD 100 AS day_of_month
FROM tableName
WHERE myDate BETWEN 20121021 AND 20121023;
Compatibility and convenience
If you have to maintain read-only compatibility with code that expects a single textual date column, you could use a VIEW to provide that. For example for a German Gregorian DD. MMMM YYYY format, you could use code like this:
CREATE VIEW compatibleName AS
SELECT CONCAT(myDate MOD 100, ". ",
ELT((myDate DIV 100) MOD 100, "Januar", "Februar", …), ". ",
myDate DIV 10000) as dateString,
* -- or explicitely name other columns needed for compatibility
FROM tableName
Decoding strings
If you need read-write access by another application using a string format, you'll have to parse those strings yourself. You can do that at the SQL level. Useful tools are SUBSTRING_INDEX to split the string into fields and FIELD to turn a month name into a number. You might want to add a trigger to the database which will ensure that your strings will always be in a valid format which you can decompose in this way. This question gives details on how to use triggers to enforce such checks.
you can store as date directly. I am usind normal date. my mysql functions are
DELIMITER $$
DROP FUNCTION IF EXISTS `kdmtest`.`IntPart` $$
CREATE FUNCTION `kdmtest`.`IntPart` (FloatNum float) RETURNS INT
BEGIN
if (floatNum< -0.0000001) then
return ceil(floatNum-0.0000001);
else
return floor(floatNum+0.0000001);
end if;
END $$
DELIMITER ;
DELIMITER $$
DROP FUNCTION IF EXISTS `kdmtest`.`Hicri` $$
CREATE DEFINER=`root`#`localhost` FUNCTION `Hicri`(MiladiTarih date) RETURNS date
BEGIN
declare d,m,y,jd,l,n,j int;
set d=day(MiladiTarih);
set m=month(MiladiTarih);
set y=year(MiladiTarih);
if ((y>1582) or((y=1582) and (m>10)) or ((y=1582) and (m=10) and (d>14))) then
set jd=intpart((1461*(y+4800+intpart((m-14)/12)))/4)+intpart((367*(m-2-12*(intpart((m-14)/12))))/12)- intpart( (3* (intpart( (y+4900+ intpart( (m-14)/12) )/100) ) ) /4)+d-32075;
else
set jd = 367*y-intpart((7*(y+5001+intpart((m-9)/7)))/4)+intpart((275*m)/9)+d+1729777;
end if;
set l=jd-1948440+10632;
set n=intpart((l-1)/10631);
set l=l-10631*n+354;
set j=(intpart((10985-l)/5316))*(intpart((50*l)/17719))+(intpart(l/5670))*(intpart((43*l)/15238));
set l=l-(intpart((30-j)/15))*(intpart((17719*j)/50))-(intpart(j/16))*(intpart((15238*j)/43))+29;
set m=intpart((24*l)/709);
set d=l-intpart((709*m)/24);
set y=30*n+j-30;
return concat(y,'-',m,'-',d);
END $$
DELIMITER ;
DELIMITER $$
DROP FUNCTION IF EXISTS `kdmtest`.`Miladi` $$
CREATE FUNCTION `kdmtest`.`Miladi` (HicriTarih date) RETURNS date
BEGIN
declare d,m,y,jd,l,n,j,i,k int;
set d=day(HicriTarih);
set m=month(HicriTarih);
set y=year(HicriTarih);
set jd=intPart((11*y+3)/30)+354*y+30*m-intPart((m-1)/2)+d+1948440-385;
if (jd> 2299160 ) then
set l=jd+68569;
set n=intPart((4*l)/146097);
set l=l-intPart((146097*n+3)/4);
set i=intPart((4000*(l+1))/1461001);
set l=l-intPart((1461*i)/4)+31;
set j=intPart((80*l)/2447);
set d=l-intPart((2447*j)/80);
set l=intPart(j/11);
set m=j+2-12*l;
set y=100*(n-49)+i+l;
else
set j=jd+1402;
set k=intPart((j-1)/1461);
set l=j-1461*k;
set n=intPart((l-1)/365)-intPart(l/1461);
set i=l-365*n+30;
set j=intPart((80*i)/2447);
set d=i-intPart((2447*j)/80);
set i=intPart(j/11);
set m=j+2-12*i;
set y=4*k+n+i-4716;
end if;
return concat(y,'-',m,'-',d);
END $$
DELIMITER ;

'0000-00-00 00:00:00' can not be represented as java.sql.Timestamp error

I have a database table containing dates
(`date` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00').
I'm using MySQL. From the program sometimes data is passed without the date to the database. So, the date value is auto assigned to 0000-00-00 00:00:00
when the table data is called with the date column it gives error
...'0000-00-00 00:00:00' can not be represented as java.sql.Timestamp.......
I tried to pass null value to the date when inserting data, but it gets assign to the current time.
Is there any way I can get the ResultSet without changing the table structure?
You can use this JDBC URL directly in your data source configuration:
jdbc:mysql://yourserver:3306/yourdatabase?zeroDateTimeBehavior=convertToNull
Whether or not the "date" '0000-00-00" is a valid "date" is irrelevant to the question.
"Just change the database" is seldom a viable solution.
Facts:
MySQL allows a date with the value of zeros.
This "feature" enjoys widespread use with other languages.
So, if I "just change the database", thousands of lines of PHP code will break.
Java programmers need to accept the MySQL zero-date and they need to put a zero date back into the database, when other languages rely on this "feature".
A programmer connecting to MySQL needs to handle null and 0000-00-00 as well as valid dates. Changing 0000-00-00 to null is not a viable option, because then you can no longer determine if the date was expected to be 0000-00-00 for writing back to the database.
For 0000-00-00, I suggest checking the date value as a string, then changing it to ("y",1), or ("yyyy-MM-dd",0001-01-01), or into any invalid MySQL date (less than year 1000, iirc). MySQL has another "feature": low dates are automatically converted to 0000-00-00.
I realize my suggestion is a kludge. But so is MySQL's date handling.
And two kludges don't make it right. The fact of the matter is, many programmers will have to handle MySQL zero-dates forever.
Append the following statement to the JDBC-mysql protocol:
?zeroDateTimeBehavior=convertToNull&autoReconnect=true&characterEncoding=UTF-8&characterSetResults=UTF-8
for example:
jdbc:mysql://localhost/infra?zeroDateTimeBehavior=convertToNull&autoReconnect=true&characterEncoding=UTF-8&characterSetResults=UTF-8
Instead of using fake dates like 0000-00-00 00:00:00 or 0001-01-01 00:00:00 (the latter should be accepted as it is a valid date), change your database schema, to allow NULL values.
ALTER TABLE table_name MODIFY COLUMN date TIMESTAMP NULL
As an exteme turnaround, when you cannot do an alter to your date column or to update the values, or while these modifications take place, you can do a select using a case/when.
SELECT CASE ModificationDate WHEN '0000-00-00 00:00:00' THEN '1970-01-01 01:00:00' ELSE ModificationDate END AS ModificationDate FROM Project WHERE projectId=1;
you can try like This
ArrayList<String> dtlst = new ArrayList<String>();
String qry1 = "select dt_tracker from gs";
Statement prepst = conn.createStatement();
ResultSet rst = prepst.executeQuery(qry1);
while(rst.next())
{
String dt = "";
try
{
dt = rst.getDate("dt_tracker")+" "+rst.getTime("dt_tracker");
}
catch(Exception e)
{
dt = "0000-00-00 00:00:00";
}
dtlst.add(dt);
}
I wrestled with this problem and implemented the URL concatenation solution contributed by #Kushan in the accepted answer above. It worked in my local MySql instance. But when I deployed my Play/Scala app to Heroku it no longer would work. Heroku also concatenates several args to the DB URL that they provide users, and this solution, because of Heroku's use concatenation of "?" before their own set of args, will not work. However I found a different solution which seems to work equally well.
SET sql_mode = 'NO_ZERO_DATE';
I put this in my table descriptions and it solved the problem of
'0000-00-00 00:00:00' can not be represented as java.sql.Timestamp
There was no year 0000 and there is no month 00 or day 00. I suggest you try
0001-01-01 00:00:00
While a year 0 has been defined in some standards, it is more likely to be confusing than useful IMHO.
just cast the field as char
Eg: cast(updatedate) as char as updatedate
I know this is going to be a late answer, however here is the most correct answer.
In MySQL database, change your timestamp default value into CURRENT_TIMESTAMP. If you have old records with the fake value, you will have to manually fix them.
You can remove the "not null" property from your column in mysql table if not necessary. when you remove "not null" property no need for "0000-00-00 00:00:00" conversion and problem is gone.
At least worked for me.
I believe this is help full for who are getting this below Exception on to pumping data through logstash
Error: logstash.inputs.jdbc - Exception when executing JDBC query {:exception=>#}
Answer:jdbc:mysql://localhost:3306/database_name?zeroDateTimeBehavior=convertToNull"
or if you are working with mysql

Categories