lotus notes search by date with Java api - java

I'm trying to select records by date from a Lotus Notes database and have run into trouble with correctly formatting the date.
Here's the relevant code:
public void runNotes() {
Session s;
try {
s = NotesFactory.createSession((String)null, (String)null, "mypassword");
Database hkDB =
s.getDatabase("NBHDH001/YNM", "H\\DHH00001.nsf", false);
DocumentCollection docs = hkDB.search("[Date]>[2012/03/20]");
Date is a field in the record, and when I looked up records (with FTSearch), the date came back in the format above: [yyyy/mm/dd].
The parameter of the search is what I need here.
i.e. what should I put instead of "[Date]>[2012/03/20]"
I tried various constructions with Calendar and DateFormat, but it's not coming together...
Any suggestions?

You should get rid of the square brackets on the field name. The search method expects a Notes Formula, like what you'd put into a view selection formula:
"Date > [03/20/2012]"
It might also be required that dates are in mm/dd/yyyy format, though if you are in a non-US locale I'm not 100% sure.

You mentioned that you have been doing full text searches in the database, so it is definitely worth mentioning this... If the database actually has a full text index, then you may want to consider using the NotesDatabase.FTSearch() method instead of NotesDatabase.Search(). The FTSearch method will be considerably faster for a large database.
The syntax for FTSearch is different from the syntax for Search. You could use either "FIELD Date > 03/20/2012" or "[Date] > 03/20/2012".

Related

Android Studio project not reading correctly from SQLite database?

I've been struggling with this for days now and can't work out what's wrong. The thing is, I am not getting errors at the moment. Im just not producing the result I hoped for. I am trying to read from a specific record in my sqlite database where the data is a week ago today - I am trying to get the weather on this day, which is in my database. Here is my DB code for the method I am using:
public long homepageTB(){
LocalDate now = LocalDate.now();
LocalDate lastWeek = now.minusDays(7+now.getDayOfWeek().getValue()-1);
LocalDate currentDate = now.minusDays(now.getDayOfWeek().getValue());
String[] lweek = new String[1];
lweek[0] = String.valueOf(lastWeek);
String lastwk = String.valueOf(lastWeek);
long rv = -1; //<<<< default return to indicate no such row
SQLiteDatabase DB=this.getReadableDatabase();
Cursor cursor=DB.rawQuery("select weather from dailyQuiz1 where date =?",lweek);
if (cursor.moveToFirst()) {
rv = cursor.getLong(cursor.getColumnIndex("weather"));
}
System.out.println(lweek[0]);
System.out.println(rv);
return rv;
}
At the moment, this correctly returns the data week ago in format: 2022-01-31
and returns rv: -1 (which means it can't find the record). However, the record is there in my database:
So realistically I don't want -1 to be returned as I would want the variable in another class I am calling it from to now hold the value of the weather, which you can see in my database is 'Rainy'. Any ideas what I've done wrong or what is a better approach? I feel it will be something so obvious but I've been trying so many things for the past few days :( Thanks for the help
With the exception that you will have an issue with the returned value being 0 if the data is found
i.e. you are getting a long from a text value when using rv = cursor.getLong(cursor.getColumnIndex("weather")) so instead of crashing when trying to convert Rainy to a long 0 is given.
What you have shown works as expected. That leaves the issue to probably be that the database does not in fact contain a row where the date column does equal the String 2022-01-31.
You need to ensure that what is in the actual database being used is as expected (your image appears to be from a tool rather than the actual database and often issues are due to differences).
So in Android Studio run the App and get to a point where it is awaiting for user interaction. The click on App Inspection do you see the same data? e.g. it should look like (not all columns have been included in the example):-
If not then your issue is that the data is not being added as expected and that needs to be corrected.
Otherwise click on the Query Icon
Enter and run SELECT length(date), * FROM dailyquiz1 WHERE date like '2022-01%' e.g. :-
if the first column returned is > 10 then there is an issue with the data that is being stored, as it contains additional data.
if the first column returned is < 10 then you are storing data that is shorter than it should be.
if no data is returned then the data stored is even further away from what it should be.

Query using setDate does not find results - cannot see final-query with parameters

I have an SQL which looks into a dimension table (which stores every dates until year 2020) and then shall retrieve the todays row.
I watched into the table, todays date is in there.
The problem is, that SQL does not return any result.
I am thinking of a problem related to the use of java.sql.PreparedStatement.setDate method.
In past i think this was working fine, now I did some kine of regression test and it failed. The differences to the past are having Oracle 12 DB now instead of 11 in past and running it on CentOS 6.5 instead of AIX.
On search I found this topic here:
Using setDate in PreparedStatement
As far as I can see, I am doing as suggested.
Heres the java code and the query:
public static String SELECT_DATUM = "SELECT TIME_ID, DATE, DAY_NAME, WEEK_NAME, MONTH_NAME, YEAR_NAME, SORTING, RELATIONDATE, VALID_TO, VALID_FROM FROM DIM_TIME WHERE DATE = :date";
java.util.Calendar now = Calendar.getInstance();
now.clear(Calendar.HOUR);
now.clear(Calendar.MINUTE);
now.clear(Calendar.SECOND);
now.clear(Calendar.MILLISECOND);
Date tmpDate = now.getTime();
Date tmpDate2 = new Date(((java.util.Date)tmpDate ).getTime());
statement.setDate(1, tmpDate2 );
I notice that getTime() is called twice. But I dont think its that bad.
I also noticed some displaying formats:
in Database the date-colums shows me the date like this: '08.11.2015'
in java while debugging tmpDate2 shows me a date like this: '2015-11-08'
in java while debugging tmpDate shows me a date like this 'Sun Nov 08 12:00:00 CET 2015'
But again, these are just display formattings while it is a dateobject in background and a date-type in database. I would expect that je JDBC driver would map this itself without formattings, that why we are using setDate method and not setString.
What am I doing wrong? What could I do for further debugging to get it?
I would like see the resulting SQL query which is finally executed with the parameter.
I tried this sql on db isntance:
SELECT * FROM v$sql s WHERE s.sql_text LIKE '%select time%' ;
but only getting this then: "... where date = trunc(:1 )"
On this row at least I can see that it was using the right schema I expected it to use and where I checked whether todays date is available.
Edit:
something I found out:
I saw another code using the same function but giving an GregorianCalendar instead Calendar. When using
new GregorienCalandar();
instead of
Calendar.getInstance();
Theres no difference.
But when I assign a date and dont let the system take the current time, then it works:
Using
new GregorianCalendar(2015, Calendar.NOVEMBER, 8);
Would retrieve the row I want from SQL.
Zsigmond Lőrinczy posted this answer as comment:
Try this: SELECT TIME_ID, DATE, DAY_NAME, WEEK_NAME, MONTH_NAME,
YEAR_NAME, SORTING, RELATIONDATE, VALID_TO, VALID_FROM FROM DIM_TIME
WHERE DATE = TRUNC (:date) – 3 hours ago
This works for my problem.
I am writing this as reponse to check it later as answer on this question if hes not going to write his own response (to get the reputation-points).
But I am wondering how I could get the same by preparing on java.
The code uses the clear-methods, which where released into an own method named 'trunc'. I think the programmer intendet to do this instead of TRUNC in SQL. I am wondering if it werent possible to do so in java and if yes, how?
Edit:
And I am wondering why a TRUNC is needed at all. Because the column in Database is of type Date an not Timestampt. So wouldnt there be an automatically trunc? I would expect this. Why do I need a trunc on SQL?

Java play framework 2.0.4 ebean query

I am wondering how to query the database using the model in play 2.0 with a query like the one I listed below. I didn't see an option to pass in direct sql into the play framework 2.0.
I am trying to get a list of the expenses from a particular month.
SELECT * FROM Expensesdb.expense
WHERE month(expense.purchase_date) = 01
The option I see is to query for all the expenses and then parse each one for the month they are listed using the Date object.
I think there should be an efficient way, I can't seem to find a way to do this using ebean with Java play framework 2.0 to perform this query.
Update
Thanks Nico, I tried the exact code you have, with DateTime and I tried to use the code below, it doesn't return any Expenses. Am I doing something wrong?
Calendar calendar = Calendar.getInstance();
calendar.set(2012, 0, 01);
Date startDate = calendar.getTime();
calendar.set(2012, 0, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
Date endDate = calendar.getTime();
List<Expense> expenses = find.where().between("purchaseDate", startDate, endDate).findList();
return expenses;
I see two options:
1 - Using Ebean mapping
The idea is to search the expenses between the beginning and the end of the month, something like:
Datetime firstDayOfMonth= new Datetime().withDayOfMonth(1);
Datetime lastDayOfMonth = new Datetime().dayOfMonth().withMaximumValue();
return finder.where()
.between("purchaseDate", firstDayOfMonth, lastDayOfMonth).findList();
2 - Using RawSQL
For this, please take a look at the Ebean documentation.
The main drawback of raw sql is that this code will not be portable for different SQL servers (if you don't plan to use several db engine, it will not matter).
+1 for #nico_ekito
On the other hand, while you are suggesting getting all rows from DB and then parsing them in the loop, I'd rather suggest to parse them... while creating and store in format easier to search and index. Just create additional column(s) in your DB, and override save() and/or update(Object o) methods in your model, to make sure, that every change will set the field, ie use String purchasePeriod for storing string like 2012-11;
you can find then:
# in November of ANY year
SELECT * FROM table WHERE purchase_period LIKE '%-11';
# in whole 2012
SELECT * FROM table WHERE purchase_period LIKE '2012-%';
# in December 2012
SELECT * FROM table WHERE purchase_period LIKE '2012-12';
alternatively you can divide it into two Integer fields: purchaseYear, purchaseMonth.
For the first scenario the overriden save() method in the Expense model can look ie like this:
public void save() {
this.purchaseDate = new Date();
this.purchasePeriod = new SimpleDateFormat("yyyy-MM").format(this.purchaseDate);
super.save();
}

Oracle Date Literal [DD-MON-RR HH.MI.SSXFF AM]

I'm trying to use the timestamp format [DD-MON-RR HH.MI.SSXFF AM] to insert my date.
I can't modify the database settings in anyway possible, and I have to insert the date through a JAVA's string format (I can't modify the class that defined it either).
Having said that, I need to literally reconstruct the format string-by-string without tempering the other class/db.
The nls settings for date is DD-MON-RR. 12-JUN-2012 and 12/JUN/2012 worked perfectly fine.
But I find it difficult to recreate the timestamp part of the date.
Listed below is a few format I've tried.
'12-JAN-12' < success
'12/JAN/2012' < success
'12/JAN/2012 10.30.25.000 AM < failed
'12/JAN/2012 10:30:25.000 AM < failed
Did messed up the : or .? Or was the zero(s) aren't enough for miliseconds? Been in this trouble for hours now.
Thanks in advance.
EDIT
After a few reasoning sessions, the seniors gave their permission to alter the model class. Everything's good now. Thanks for the help and suggestions.
Since you must send a string to the DB, you must rely on the implicit conversion of the oracle DB to the DATE type.
Since you can't change the DB settings, the only thing I can suggest is changing the session settings.
So, if you can run commands against the DB, try:
Statement st = conn.createStatement();
st.execute("alter session set NLS_DATE_FORMAT='dd/mm/yyyy hh24:mi:ss'");
(or some other format (it's not recomended to use mon in your format because it might involve NLS_TERRITORY too))

How to send a Timestamp field to Oracle stored proc. from Java despite the DB config?

I'm making a request from a java webapp to an Oracle' stored procedure which happens to have a Timestamp IN parameter.
The way info travels is something like:
javaWebApp --} webservice client --} ws --} storedProcedure
And I send the Timestamp param as a formatted string from the webservice client to the ws.
In the testing environment, it works sending:
SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MMM-yyyy hh:mm:ss a");
input.setTimestampField(dateFormat.format(new Date()));
As you see, a formatted string is sent. But in the production environment, it raises an exception
ORA-01830: date format picture ends before converting entire input string.
It relates to the format not being the same, possibly due to differences in configuration from one DB to the other. I know the testing environment should be a replica of the production site, but it is not in my hands to set them properly. And I need to send the Timestamp-as-a-formatted-string field despite the way they setup the database. Any ideas? Thanks in advance.
**** EDIT ****: I've found the way to make it work properly despite the particular configuration. It is as simple as setting the call instruction in the web service with the appropiate Oracle instructions. I mean, the calling to the Oracle stored procedure went from
"call PACKAGE.MYPROCEDURE(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"
to
"call PACKAGE.MYPROCEDURE(?,?,?,?,?,?,TO_TIMESTAMP(?, 'DD-MM-YYYY HH24:MI:SS'),?,?,?,?,?,?,?,?,?,?,?)"
while the format I set in the procedure calling matches the format sent by the webapp using the SimpleDateFormat stated in the original question, slightly modified:
SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
Thank you all for the help and the ideas.
The default NLS_DATE_FORMAT generally doesn't include the time and only a two-digit year. It is probably either DD-MM-YY or MM-DD-YY.
If the WS receives a string and the database stored procedure needs a timestamp, then the two of them will need to negotiate the format mask. Either the WS, when it connects to the database, should set an explicit date format, or the database should be able to accept a string and convert it using a hard-coded format.
Unless there is some particular negotiation you have defined in the WS, nothing the JavaWebApp or WebServiceClient will be able to influence the format that the database assumes the WS is using.
All that said, I'd have a look around any other code at your end and see if there's anything doing a similar translation. You may find something else using a specific format.
What does your query look like in the input prepared statement? That error indicates that Oracle doesn't like the date format you have passed in. Your test environment may have a different NLS_DATE_FORMAT set on the database or machine/driver being used.

Categories