JdbcTemplate queryForList changing the database order - spring

I'm using the queryForList method to fetch the data for the following sql.
String sql = "select * from my_table ORDER BY ? ? LIMIT ?, ?";
return jdbcTemplate.queryForList(sql,new Object[]{param1,param2,
param3,param4});
I can see that the order is altered when the data is returned.To confirm, I tried using simple JDBC as follows
try {
Connection conn = jdbcTemplate.getDataSource().getConnection();
//Sample values param1 -> field1, param2 -> asc/desc, param3 -> 0, param4 -> 25
String sql = "select * from my_table ORDER BY "+param1+" "+param2+" LIMIT "+param3+", "+param4;
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(sql);
while(rs.next()){
System.out.println("Name = "+rs.getString("field1")+" Type = "+rs.getString("field2"));
}
} catch (SQLException e) {
e.printStackTrace();
}
Here, the print statement gives the output as desired. I want to use queryForList as it suits our data format requirements. How can I make sure that the order is maintained in queryForList?

You cannot pass the order by as parameters - ORDER BY ? ?. This will result in ORDER BY "firstSort", "secondSort"rather than ORDER BY firstSort, secondSort.

Related

Oracle OJDBC MERGE Statement and Generated Keys

Does Oracle ~>12 support generated keys using a Merge statement? Some sudo code..
MERGE INTO TARGET_TABLE TRG
USING (SELECT CAST(? AS NUMBER) AS ID FROM DUAL) SRC
ON (TRG.ID = SRC.ID)
WHEN MATCHED THEN UPDATE SET....
WHEN NOT MATCHED THEN
INSERT(ID....)
VALUES(MYSEQ.NEXTVAL...)
The prepared statement is set up;
try (PreparedStatement pstmt =
connection.prepareStatement(
loadStatement(sqlName, connection, getClass()), new String[] {ID})) {
...
int inserted = pstmt.executeUpdate();
ResultSet rs = pstmt.getGeneratedKeys();
List<Long> keys = new ArrayList<>(inserted);
while (rs.next) {
rs.getLong(1);
}
return keys;
...
I have in-memory tests where the connection uses the H2 driver running the very same SQL and PreparedStatment and that returns the generated key just fine, but Oracle does not.
Reviewing the docs it would suggest it does not?
Thanks!

"hints" formatted query output using oracle jdbc driver

Is it possible to get "hints" formatted query output using oracle jdbc driver?
example query
Select /*insert*/ * from sample_table
or
Select /*html*/ * from sample_table
looks like the stmt.executeQuer is just ignoring formatting "hints" and only return Select * results
try {
stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("Select /*insert*/ * from sample_table where ID = 1");
while (rs.next()) {
inserts.add(rs.getString(1));
}
} catch (SQLException e) {
log.error("SQL Error", e);
} finally {
UPD: As mentioned in the comments the /*insert*/ "hint" is specific to the SQL Developer and SQLcl clients.
I was able to get the query formatted output from SQLcl client
The eventual goal is to get formatted query output from Java code.
So re-phrasing the question: how to run query and get output through SQLcl using java ?

Oracle is having issues with hibernate generated query, generates query with _ in row num

I am using hibernate and using criteria query, database is Oracle. The below is the query that gets generated.
"
WITH query AS (
SELECT inner_query.*,
ROW_NUMBER() OVER (ORDER BY CURRENT_TIMESTAMP) as __hibernate_row_nr__
FROM (
select this_.MODIFIEDTIME as MODIFIED1_1_1_,
this_.FIELDNAME as FIELDNAM2_1_1_,
this_.EMPNBR as EMPNBR3_1_1_
from EMPLOYEEAUDIT this_
left outer join EMPLOYEE employee2_ on this_.EMPNBR=employee2_.EMPNBR
) inner_query
)
SELECT MODIFIED1_1_1_,FIELDNAM2_1_1_,EMPNBR3_1_1_
FROM query WHERE __hibernate_row_nr__ >= 1
AND __hibernate_row_nr__ < 10;"
It is throwing the below error:-
SQL Error: 911, SQLState: 22019
ORA-00911: invalid character
However, if i take the SQL query and repalce the hibernate_row_nr with hibernate_row_nr__ and run it in DbVisualizer it works. It seems Oracle is not able to recognize starting '_' as valid characters. How to fix this issue?
Below is my java code:-
public List<Employee> getEmployeeList(int start, int limit, AgSort sorter) throws UIFilterException {
DetachedCriteria detached = getEmployeeListCriteria(sorter, filters);
return (List<DealSetupAudit>) hibernateTemplate.findByCriteria(detached, start, limit);
}
private DetachedCriteria getEmployeeListCriteria(AgSort sorter) throws UIFilterException {
DetachedCriteria detached = getBaseCriteria(DealSetupAudit.class, sorter);
return detached;
}
protected <T> DetachedCriteria getBaseCriteria(Class<T> genericType, AgSort sorter) throws UIFilterException {
DetachedCriteria criteria = DetachedCriteria.forClass(genericType);
addSorter(criteria, sorter);
return criteria;
}
protected void addSorter(DetachedCriteria criteria, AgSort sort) {
if (sort != null) {
Order order = null;
if (sort.getDir().equalsIgnoreCase(Constants.DESC)) {
order = Order.desc(sort.getColumn());
} else {
order = Order.asc(sort.getColumn());
}
criteria.addOrder(order);
}
}
I am using Hibernate4, below is my application.properties :-
oracle.datasource.driver-class-name=oracle.jdbc.OracleDriver
oracle.datasource.url=******
oracle.datasource.username=*****
oracle.datasource.password=*****
oracle.jpa.database-platform=org.hibernate.dialect.Oracle10gDialect
oracle.jpa.properties.hibernate.dialect=org.hibernate.dialect.Oracle10gDialect
Double quotes? Usually a really, really bad idea. I'd suggest you to avoid such things and use valid column names / aliases.
SQL> select dname _invalid_alias_
2 from dept
3 where deptno = 10;
select dname _invalid_alias_
*
ERROR at line 1:
ORA-00911: invalid character
SQL> select dname "_valid_alias_"
2 from dept
3 where deptno = 10;
_valid_alias_
--------------
ACCOUNTING
SQL>

How to use ampersand in JDBC?

In oracle we using select * from table_name where column_name=&value in similar way how to use ampersand in JDBC?
stmt = conn.createStatement();
String sql;
sql="select emp_name from employees"+" where emp_no=?";
ResultSet rs=stmt.executeQuery(sql);
while(rs.next()){
String emp_name=rs.getString("emp_name");
System.out.println(emp_name);
}
i wrote the above code but it is not working(showing error)
Did you read the article I provided the link to?
You use the question mark ? to point out places in your query where you want to specify a parameter, and you have to use PreparedStatement. I can't test it, but it should be something like this:
// some code to obtain the Connection object
PreparedStatement stmt = null;
String yourQuery = " SELECT emp_name FROM employees WHERE emp_no = ? ";
try {
stmt = conn.prepareStatement(yourQuery);
stmt.setLong(1, 252);
ResultSet rs = stmt.executeQuery();
while(rs.next()) {
String emp_name = rs.getString("emp_name");
System.out.println(emp_name);
}
} finally {
// close the stmt etc.
}
I'd suggest using a PreparedStatement - from memory it's something like
Connection conn = getConnection();
PreparedStatement pstmnt = conn.prepareStatement("Select * from employees where emp_no =?");
pstmnt.setLong(1,emp_no);
ResultSet rs = pstmnt.executeQuery();
but the link that #Przemyslaw Kruglej high light above will almost certainly have a good example ( I haven;t read it though ... )

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)

Resources