SQL SELECT and timestamp columns - java

In my application i have a java Timestamp dateCreated, which is inserted to a mysql Timestamp colum. Inserting is no problem, i use a prepared statement and statement.setTimestamp(dateCreated).
Now i need to select a row with the dateCreated as unique identifier. my method gets another java Timestamp object.how does the SQL query work in this case? i havent figured out how to compare the java timestamp to the mysql one.
SELECT * FROM table WHERE timestamp_column = ???
Thanks!

In Java you will use a similar setTimestamp method as you did with the insert.
Timestamp t = ???;
String sql = "SELECT * FROM table WHERE timestamp_column = ?";
preparedStatement = conn.prepareStatement(sql);
preparedStatement.setTimestamp(t);
etc.

Related

How do you find the index/order integer of a table in an SQL database (Java)?

I know that the following code below gives me the amount of tables in an SQL database (I use SQLite), but how would I get the "order" of a table so I can make a for loop to scan through all of them?
String numtables = "String sql = “SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = 'database’ ”;
pst = con.prepareStatement(numtables);
ResultSet numt = pst.executeQuery(numtables);
int num = ((Number) rs1.getObject(1)).intValue();
The correct query should be (your talking about tables in a db)
SELECT * FROM my_db.sqlite_master WHERE type='table' order by rootpage;
The root page number for any index or table can be found by querying the rootpage.
They are not necessarily subsequent numbers.
then you can explore the result set with the usual
while (rs.next())
Of course take care of the syntax errors, and use the Preparestatement strategy as often as you can, as other suggest.

Teradata JDBC not recognizing PreparedStatement parameter as VARCHAR without quotes

I am using JDBC PreparedStatement to query a Teradata database from a web service. My table has a PHONE_NUMBER column, stored as VARCHAR(10). I have always used PreparedStatement setString() to supply the parameter for this column, like below:
String myPhoneNumber = "5551234567";
String sql = "SELECT * FROM MYTABLE " +
"WHERE PHONE_NUMBER = ? ";
PreparedStatement p_stmt = db.getPreparedStatement(sql);
p_stmt.setString(1, myPhoneNumber);
ResultSet rs = db.executeQuery(p_stmt);
It returns correct results, but I noticed the CPU Teradata is using for this query is quite high. According to the EXPLAIN plan, it appears that Teradata is interpreting the myPhoneNumber parameter as a FLOAT, instead of VARCHAR, and so it has to do a data conversion to compare it to the VARCHAR column PHONE_NUMBER. Here is an excerpt of the EXPLAIN plan:
...
MYDATABASE.MYTABLE.PHONE_NUMBER (FLOAT, FORMAT
'-9.99999999999999E-999'))= 5.55123456700000E 009)
So, I came up with the below, which showed a great improvement in CPU usage (99.86% improvement):
String myPhoneNumber = "5551234567";
String sql = "SELECT * FROM MYTABLE " +
"WHERE PHONE_NUMBER = ''||?||'' ";
PreparedStatement p_stmt = db.getPreparedStatement(sql);
p_stmt.setString(1, myPhoneNumber);
ResultSet rs = db.executeQuery(p_stmt);
So my question is why is this necessary? Shouldn't setString tell JDBC to tell Teradata to expect a String/VARCHAR parameter?
Thanks!
Have you tried String myPhoneNumber = "'5551234567'";
Note -- The inclusion of the single quotes to wrap the value.
If you look at the example in the Teradata manuals here, you will see that a Query Band being set the same way as the OP's first example arrives as expected without single quotes wrapping it. It would seem to me this behavior in the first example of the OP is expected.
EDIT
The sample code provided by Teradata for their JDBC driver is using java.sql.PreparedStatment. With this their example program uses setString without any tricks to provide a string value for an INSERT statement. Sample Code If you are not able to replicate that behavior, I would open an incident with the Teradata GSC.

DB select with java util date

The DB persist java.util.date and i need a query to get all the data between 2 Dates with only using java.util.date.
I use the JPA 2.1
String sql = "SELECT * FROM table WHERE created > '"+date1+"' AND created < '"+date2+"'";
This query provides always a List with 0 elements
The problem is that your dates are being added to the SQL query as string values. The database is getting something like:
String sql = "SELECT * FROM table WHERE created > 'Wed May 25 14:33:18 SAST 2016' and created < 'Wed May 25 14:33:18 SAST 2016'";
The database is seeing it as a string and that explains why it isn't working.
The single best way to resolve it is use bind variables::
String sql = ""SELECT * FROM table WHERE created > ? AND created < ?"
//Create the query object using that SQL string, then set values
sqlQuery.setParameter(1, date1);
sqlQuery.setParameter(2, date2);
Then execute the prepared statement.

How to use to_char function in JPA to get records from a timestamp

I am try to query from and database using eclipse link using entities. when I use normal query records are returned from current date by when I use JPA zero records are returned. Where could I be doing wrong, Or how can I use to_char function in JPA my database is postgresql.
normal sql query that returns records
select *
from mytable
where to_char(transaction_date, 'YYYY-MM-DD') = '2016-01-19';
MyEntity
#Temporal(javax.persistence.TemporalType.DATE)
private Date transaction_date;
EntityManager e = EntityMgr.MyFact().createEntityManager();
e.getTransaction().begin();
Query qry = e.createQuery("from MyEntity u where u.transaction_date=?1");
qry.setParameter(1, new Date(), TemporalType.DATE);
Have you tried with qry.setParameter(1, new Date(), TemporalType.TIMESTAMP);
You can use to_char function using operator
like
OPERATOR('ToChar', transaction_date,'YYYY-MM-DD')= '2016-01-19';

Standard current time function using JDBC

When we work with JPA and JPQL we can use some date/time expressions which make the query DMBS independent. For instance let's say if I want to set the ending time of a session in my database I could simply use CURRENT_TIMESTAMP expression as follows:
String jpql = "UPDATE SessionJpa s SET s.end = CURRENT_TIMESTAMP WHERE s.id = :id";
entityManager.getTransaction().begin();
Query query = entityManager.createQuery(jpql);
query.setParameter("id", someIdValue);
query.executeUpdate();
entityManager.getTransaction().commit();
This way the same JPQL should work with Oracle, MySQL, PostreSQL, etc as DBMS.
Now my question: Is there a way to achieve the same when using JDBC instead of JPA?
This is what I have so far:
String sql = "UPDATE Sessions SET end = SYSDATE WHERE id = ?";
try (Connection connection = dataSource.getConnection();
PreparedStatement statement = connection.prepareStatement(sql)) {
statement.setLong(1, someIdValue);
int updatedRows = statement.executeUpdate();
// ...
} catch(SQLException ex) {
Logger.getLogger(SessionsBean.class.getName()).log(Level.SEVERE, null, ex);
}
But of course SYSDATE is not a generic expression and it will work only with Oracle as DBMS most likely.
Apart from the fact that most databases have the SQL standard CURRENT_TIMESTAMP, JDBC drivers might support the JDBC escape functions and translate those to the database specific variant. These escapes are called using {fn <function>}, and are listed in Appendix C of the JDBC 4.2 specification.
Specifically (from C.3):
CURRENT_DATE[()] Synonym for CURDATE()
CURRENT_TIME[()] Synonym for CURTIME()
CURRENT_TIMESTAMP[()] Synonym for NOW()
CURDATE() The current date as a date value
CURTIME() The current local time as a time value
NOW() A timestamp value representing the current date and time
So the JDBC escape equivalent would be:
String sql = "UPDATE Sessions SET end = {fn CURRENT_TIMESTAMP} WHERE id = ?";
(or {fn NOW()})
Note that although JDBC drivers are required to support the escape syntax, they are not actually required to support all functions. Check the result of DatabaseMetaData.getTimeDateFunctions() for your driver.
You can find a related discussion here - Is Oracle's CURRENT_TIMESTAMP function really a function?.
Summary is that - CURRENT_TIMESTAMP is defined by the SQL standard and any compliant database system should recognize it.
You can get the same by defining another parameter for the date, such as:
String sql = "UPDATE Sessions SET end = ? WHERE id = ?";
...
statement.setTimestamp(1, new java.sql.Timestamp(new java.util.Date().getTime()));
statement.setLong(2, sesion.getId());
I hope this works

Categories