JDBC PreparedStatement, UNION Select and parameter passing - jdbc

Ok, I know the answer is simple and I'm going to feel pretty dumb but...
Java JDK 1.7, Sybase JDBC driver
Code snipit:
String sql = "select <blah>
from <blah blah>
where date1 = ?
UNION
select <blah>
from <blah blah>
where date2 = ?";
Connection conn = ConnectionManager.getConnection();
PreparedStatement stmt = conn.prepareStatement(sql);
logger.info("parmemeter count: " + stmt.getParameterMetaData().getParameterCount());
stmt.setDate(1, new java.sql.Date(date.getTime()));
stmt.setDate(2, new java.sql.Date(date.getTime()));
ResultSet rs = stmt.executeQuery();
while rs.next()) {
// the rest of the code
}
So why is the parmeter count only 1?
Running the program throws an error complaining: java.sql.SQLException: Invalid parameter index 2.
If I reduce the sql to either piece and reduce the setDate() to only 1 it works just fine.
The SQL with the UNION runs just fine in an interactive sql session (? filled in with a date of course)

I just ran into this problem, and this thread was very helpful. It's not the union clause that's throwing errors; it's the date that you're passing in. If you're using to_date () (unclear from your code snippet), you need to be passing a string in the query (instead of a date). Good luck!

Related

Optional parameter in query does not work for db2 but works in oracle

Below query works fine for Oracle database, but for Db2 it throws error sqlcode -417.
I have looked up similar problems but did not get any definitive answer:
#Query(value = "select * from tableName f where (aC is null or f.a_c = aC)", nativeQuery = true)
Page<tablename> findByFilters(String aC, Pageable pageable);
On execution the error code is -417
One way to solve this problem would be to rewrite the query as the following:
select * from tableName f where f.a_c = coalesce(aC, f.a_c)
The form of query above is likely to be accepted. In order to find out the exact reason of the error you get, it is necessary to trace the actual SQL statement passed to Db2.
Another option of solving the problem may be to add the CAST operator, which would define the data type of your parameter:
select * from tableName f where (cast(aC as integer) is null or f.a_c = aC)
This is suggested in the description of the error you get

Parametrizing a sub query with jdbc PreparedStatement

I have the following query where the first argument itself is a subquery
The java code is:
String query = select * from (?) where ROWNUM < ?
PreparedStatement statement = conn.preparedStatement(query)
statement.setString(1, "select * from foo_table")
statement.setInt(2, 3)
When I run the java code, I get an exception. What alternatives do I have for making the first subquery statement.setString(1, "select * from foo_table") a parameter?
This is not possible, parameter placeholders can only represent values, not object names (like table names, column names, etc) nor subselects or other query elements.
You will need to dynamically create the query to execute using string concatenation, or other string formatting/templating options.

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);

Comparisons of Oracle DATE column with java.sql.timestamp via JOOQ

I am using jooq to build queries for Oracle. Everything works fine except for dates:
public static void main(String[] args) throws SQLException {
java.sql.Timestamp now = new java.sql.Timestamp(new Date().getTime());
Connection con = DriverManager.getConnection(... , ... , ...);
final Factory create = new OracleFactory(con);
Statement s = con.createStatement();
s.execute("create table test_table ( test_column DATE )");
s.execute("insert into test_table values (to_date('20111111', 'yyyymmdd'))");
// -- using to_date
ResultSet rs = s.executeQuery("select count(1) from test_table where test_column<to_date('20121212', 'yyyymmdd')");
rs.next();
System.out.println(""+rs.getInt(1));
rs.close();
// -- using a preparedstatement with java.sql.timestamp
PreparedStatement ps = con.prepareStatement("select count(1) from test_table where test_column<?");
ps.setTimestamp(1,now);
rs = ps.executeQuery();
rs.next();
System.out.println(""+rs.getInt(1));
rs.close();
// -- using jooq with java.sql.timestamp
final org.jooq.Table<org.jooq.Record> table = create.tableByName("TEST_TABLE");
final org.jooq.SelectSelectStep sss = create.select(create.count());
final org.jooq.SelectJoinStep sjs = sss.from(table);
final org.jooq.SelectConditionStep scs = sjs.where(create.fieldByName("TEST_COLUMN").lessThan(now));
System.out.println(scs.toString());
rs = s.executeQuery(scs.toString());
rs.next();
System.out.println(""+rs.getInt(1));
rs.close();
s.close();
}
Gives the following output:
1
1
select count(*) from "TEST_TABLE" where "TEST_COLUMN" < '2012-12-12 19:42:34.957'
Exception in thread "main" java.sql.SQLDataException: ORA-01861: literal does not match format string
I would have thought that JOOQ would check the type of Object in lessThan(Object)
to determine whether it can come up with a reasonable conversion, but apparently it
just does an Object.toString() in this case. I also remember that I never had issues with date queries via JOOQ in MySQL (although this is a while back). What am I doing wrong?
I suspect that this issue is due to the fact that create.fieldByName() doesn't know the type of the column (hence, Object), and coerces that unknown type on the right hand side of the comparison predicate. That should be fixed in jOOQ. I have registered #2007 for this:
https://github.com/jOOQ/jOOQ/issues/2007
In the mean time, try explicitly setting the type on your field:
create.fieldByName(Timestamp.class, "TEST_COLUMN").lessThan(now)

Why a select query is running slower in Oracle than sql server

I am reading data from Oracle database by using ODP.Net with the follwing code
OracleConnection con = new OracleConnection(connectionString);
OracleCommand cmd = new OracleCommand( SELECT ID,RECORD(XMLType) FROM tbl_Name, con);
con.Open();
OracleDataReader _dataReader = cmd.ExecuteReader();
while (_dataReader.Read())
{
string rowId = _dataReader[0].ToString();
string xmlString = _dataReader[1].ToString();
adding this data into Queue for further processing
}
It working fine but in a minute it's reading only 10000 record. If I use SqlServer database it's reading 500000 record in minute having table with same schema.
Please help me if I am missing something to read data faster using ODP.NET
Thank you.
**
ANSWER:
**
I have tried with GetClobVal() and GetString Val() functions, now it is working fine.
select t.RECID, t.XMLRECORD.GetClobVal() from tableName t"
select x.RECID,x.XMLRECORD.getStringVal() from tableName x"
If we use these queries with oracle command it will run fast, but not as fast as sql server query.

Resources