Passing java.sql.Date to sql query - jdbc

This is a part of my code
java.sql.Date d1=java.sql.Date.valueOf("2011-03-02");
java.sql.Date d2=java.sql.Date.valueOf("2011-03-10");
java.sql.Date systemDate=java.sql.Date.valueOf("2011-03-04");
String sql="select id from period where '"+systemDate+"' between '"+d1+"' and '"+d2+"'";
This is my code. I want to get the id which falls between these dates. But i am not getting the desired result. I am getting back all the id present in the table.

Do you have good results when you use other SQL tools (like pgadmin for PostgreSQL or SQL Developer for Oracle)?
Is so then try to use PreparedStatement. In your case this will look like:
PreparedStatement pstmt = con.prepareStatement("select id from period where ? between ? and ?");
pstmt.setDate(1, systemDate);
pstmt.setDate(2, d1);
pstmt.setDate(3, d2);

You're not using a field from your table to compare with your date range.
What you're doing is checking if 04-03-2011 is between 02-03-2011 and 10-03-2011, which is true for every record.
What you want to do is something like this (assuming start_date is a column in your table):
String sql="select id from period where start_date between '"+d1+"' and '"+d2+"'";
(Also, I agree with the answer above that prepared statements are a better way to construct queries.)

Related

How to convert Month-Year to date in HQL/Grails?

This query is working in database
select to_date(a.year || a.month, 'YYYYMM') as dates from table a
but not working in Grails as HQL. Giving an error as "unexpected token".
How do I use this query in HQL/Grails?
As example I have month & year column. I need to show this as date in new column.
Above to_date(a.year || a.month, 'YYYYMM') as dates works fine in oracle database but it doesn't work in HQL in grails where I'm using as
executeQuery("select to_date(a.year || a.month, 'YYYYMM') as dates from table a") but this one is not working
HQL is only good if you have modeled your database table. If you really want to use this exact query, go for native SQL instead of HQL:
MyController {
Sql groovySql // package: groovy.sql
def myAction() {
def results = groovySql.rows("SELECT 'thisIsNativeSqlQuery'");
// do something with your results;
}
}
If you have modeled this table already (has Domain class) you can just fetch them all with YourDomain.list() and make a getter method that forms your date from the format you have:
Date toDate() {
​ return Date.parse("yyyyMM", "201808")​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​
}
or have transient field that does this for you, it all depends on your use case

Passing Date to NamedParameterJdbcTemplate in Select query to oracle

I have a query as below which is returning expected records when run from the SQL Developer
SELECT *
FROM MY_TABLE WHERE ( CRT_TS > TO_DATE('25-Aug-2016 15:08:18', 'DD-MON-YYYY HH24:MI:SS')
or UPD_TS > TO_DATE('25-Aug-2016 15:08:18', 'DD-MON-YYYY HH24:MI:SS'));
I think that we will not need to apply TO_DATE when we are passing java.util.Date object as date parameters but the below code snippet is silently returning me 0 records.
My SQL query in Java class is as below:
SELECT *
FROM MY_TABLE WHERE ( CRT_TS > :lastSuccessfulReplicationTimeStamp1
or UPD_TS > :lastSuccessfulReplicationTimeStamp2);
The code which executes the above query is as below but the below code snippet is silently returning me 0 records:
parameters.put("lastSuccessfulReplicationTimeStamp1", new java.sql.Date(outputFileMetaData.getLastSuccessfulReplicationTimeStamp().getTime()));
parameters.put("lastSuccessfulReplicationTimeStamp2", new java.sql.Date(outputFileMetaData.getLastSuccessfulReplicationTimeStamp().getTime()));
list = namedParameterJdbcTemplateOracle.query(sql, parameters, myTabRowMapper);
Please advise.
I guess you already found the answer but if anybody else needs it, here's what I've found:
java.sql.Date doesn't have time, just the date fields. Either use java.sql.Timestamp or java.util.Date. Both seems to be working for me with NamedParameterJdbcTemplate.
A little variation to above solution can be when your input(lastSuccessfulReplicationTimeStamp1/lastSuccessfulReplicationTimeStamp2) is a String instead of Date/TimeStamp (which is what i was looking for and found at this link -> may be it can help someone):
MapSqlParameterSource parameters = new MapSqlParameterSource();
parameters.addValue("lastSuccessfulReplicationTimeStamp1", lastSuccessfulReplicationTimeStamp1, Types.TIMESTAMP);
parameters.addValue("lastSuccessfulReplicationTimeStamp2", lastSuccessfulReplicationTimeStamp2, Types.TIMESTAMP);
list = namedParameterJdbcTemplateOracle.query(sql, parameters, myTabRowMapper);

JPA Native query on Oracle database

I'm trying to do a native query on an Oracle database involve dates but I'm just not getting something.
I have a table with a number of rows in it and I know that the record with the oid=1234 has the latest updatetimeutc field, where updatetimeutc is a Date field. So I do the following:
Query query1 = entityManager.createNativeQuery("select updatetimeutc from TABLE where oid=1234");
List<Object[]> resultList = query1.getResultList();
Object[] os = resultList.get(0);
Date date = os[0];
Query query2 = entityManager.createNativeQuery("select oid, updatetimeutc from TABLE where updatetimeutc > :d");
query.setParameter("d", date);
resultList = query.getResultList();
At this point, I'm expecting the resultList.size() == 0, but that's not what's happening. I'm getting the same row returned to me as in query1.
Can someone explain why this is happening or what I'm doing wrong?
Thanks
The solution is to make sure you are using a version of Oracle's JDBC drivers that produce a java.sql.Timestamp for native queries that return DATE field.

Operation with dates in Grocery CRUD and Codeigniter

In table Employees I have columns: start_date(dd/mm/yyyy), end_date(dd/mm/yyyy) and period(dd/mm/yyyy).
I want to put calculation in column period = end_date - start_date.
I don't now haw to take data from columns start_date and end_date and write operation for column period. Please help me to solve my problem.
This is an SQL question IMO. But you tagged it as codeigniter so I guess you need CI code to go with this.
Anyway you can use DATEDIFF on your query. Like so.
$sql = "SELECT DATEDIFF(start_date,end_date) AS DiffDate";
Then fire it up on CI using query().
$qry = $this->db->query($sql);
return $qry->result();

Is it possible to refer to column names via bind variables in Oracle?

I am trying to refer to a column name to order a query in an application communicating with an Oracle database. I want to use a bind variable so that I can dynamically change what to order the query by.
The problem that I am having is that the database seems to be ignoring the order by column.
Does anyone know if there is a particular way to refer to a database column via a bind variable or if it is even possible?
e.g my query is
SELECT * FROM PERSON ORDER BY :1
(where :1 will be bound to PERSON.NAME)
The query is not returning results in alphabetical order, I am worried that the database is interpreting this as:-
SELECT * FROM PERSON ORDER BY 'PERSON.NAME'
which will obviously not work.
Any suggestions are much appreciated.
No. You cannot use bind variables for table or column names.
This information is needed to create the execution plan. Without knowing what you want to order by, it would be impossible to figure out what index to use, for example.
Instead of bind variables, you have to directly interpolate the column name into the SQL statement when your program creates it. Assuming that you take precautions against SQL injection, there is no downside to that.
Update: If you really wanted to jump through hoops, you could probably do something like
order by decode(?, 'colA', colA, 'colB', colB)
but that is just silly. And slow. Don't.
As you are using JDBC. You can rewrite your code, to something without bind variables. This way you can also dynamically change the order-by e.g.:
String query = "SELECT * FROM PERS ";
if (condition1){
query = query+ " order by name ";
// insert more if/else or case statements
} else {
query = query+ " order by other_column ";
}
Statement select = conn.createStatement();
ResultSet result = select.executeQuery(query);
Or even:
String columnName = getColumnName(input);
Statement select = conn.createStatement();
ResultSet result = select.executeQuery("SELECT * FROM PERS ORDER BY "+columnName);
ResultSet result = select.executeQuery(
"SELECT * FROM PERS ORDER BY " + columnName
);
will always be a new statement to the database.
That means it is, like Thilo already explained, impossible to "reorder" an already bound, calculated, prepared, parsed statement. When using this result set over and over in your application and the only thing, which changes over time is the order of the presentation, try to order the set in your client code.
Otherwise, dynamic SQL is fine, but comes with a huge footprint.

Resources