NativeQuery with OpenQuery and Parameters - java

I've been triyng to create a query using a dblink with some parameters.
I'm using Hibernate 4 and the database is a MSSQL.
But I either get:
com.microsoft.sqlserver.jdbc.SQLServerException: Incorrect syntax near '#P0'.
if my query is
#Query(nativeQuery=true, value="SELECT * FROM OPENQUERY([linked_server], 'SELECT * FROM TABLE WHERE COLUM1 = ''0145A'' AND COLUMN2 LIKE ':prefix'' );")
public List<CPNT023_PART> GET_PART_AND_ANALYST(#Param(value="prefix") String prefix);
Or I get
java.lang.IllegalArgumentException: Parameter with that position [1] did not exist
if the query is
#Query(nativeQuery=true, value="SELECT * FROM OPENQUERY([linked_server], 'SELECT * FROM TABLE WHERE COLUM1 = ''0145A'' AND COLUMN2 LIKE '':prefix'' ' );")
public List<CPNT023_PART> GET_PART_AND_ANALYST(#Param(value="prefix") String prefix);
(Note the difference in the single quotes after LIKE).
If I don't use any parameters I get a correct answer. So this query:
#Query(nativeQuery=true, value="SELECT * FROM OPENQUERY([linked_server], 'SELECT * FROM TABLE WHERE COLUM1 = ''0145A'' AND COLUMN2 LIKE ''%ABC%'' ' );")
Actually works.
I'm kinda lost with this problem, I'v been triyng to search for an answer but got nowhere near a valid one.
I have to make use of OPENQUERY as the linked server is a huge Oracle database, as I need it to make the actual processing.
Thanks in advance.

Finally I didn't manage to make the querys work properly.
To solve the problem I created some stored procedures in the database with the querys and that solved everything, as the #Query annotation doen't have to deal with nested apostrophes.
Life now is easy, and keeps going on.
Bye.

Related

Can we modify the query using Statement Inspector after binding the parameters to query

Getting the query in Statement Inspector after the parameters are binded.
I am following the below links for statement inspector, can the query be modified after the parameters are binded.
https://vladmihalcea.com/hibernate-statementinspector/
https://stackoverflow.com/questions/39112308/how-i-can-configure-statementinspector-in-hibernate
For eg:
Query q = entityManager.createNativeQuery("Select * from employees where address2_id = ?");
q.setParameter(1, address2_idval);
For the above scenario if i log the query using inspector it's printing
Select * from employees where address2_id = ?
the reason i am using inspector is sometimes address2_idval can be empty(very rare case) at that time it's generating Select * from employees where address2_id = '' where address2_id is a numeric datatype in Db(POSTGRES).
I am getting the following error invalid input syntax for type numeric "".
What i am planning on implementing in inspector is if i can get Select * from employees where address2_id = '' like this in inspector block i can check with regex and replace = '' with is null.
Can anyone pls suggest if this is possible?
NOTE: We are migrating from oracle to potgres so there are tons of queries which might face this issue, so planning on implementing in one place which intercept all the queries with this scenario

SQL error an expression of non-boolean type specified in a context where a condition is expected, near 'AND'

I have the below sql
SELECT * FROM TABLE WHERE COLUMN LIKE CONCAT('%','CMP1','%') OR COLUMN LIKE
CONCAT('%','CMP2','%')
I am replacing this programatically
#Query(value = "SELECT * FROM TABLE WHERE ?1", nativeQuery = true)
List<Items> getAllItems(String param);
I had to append these OR conditions based on the user inputs so the conditions varies hence I used it as a combined OR statements.
How do I resolve this error?
Thanks in advance
Well, let's say I call getAllItems("Hello"). That means you end up trying to run SQL: "SELECT * FROM TABLE WHERE 'Hello'" which is invalid SQL for the exact reason stated: 'Hello' isn't a boolean. You can't put SQLese in that string (you can't call getAllItems("column like CONCAT('%', 'CMP1', '%')") - the point of these queries is that the SQL gets hardcoded and the dynamic data (the string param) is escaped.
You'd have to find a way to write this as a single SQL statement, or, don't use #Query.

Hibernate paging query returns no records with DB2/400 dialect

I am using Vaadin Flow together with Spring-data-jpa and Hibernate with DB2/400 dialect. I am trying to use paging queries as my dataset could be very large. I have Hibernate logging on so that I can see the statements that Hibernate is executing. It works for the first page as the Hibernate query just asks for the first 50 records. However for the second page it asks for 100 records and filters out the first 50 but the query does not return any results. A slightly simplified version of the Hibernate generated query is:
select * from (
select inner2_.*, rownumber() over(order by order of inner2_) as rownumber_ from (
select * from flxalll1 flxalll1x0_ where upper(flxalll1x0_.aoukey) like upper('%te%') fetch first 100 rows only
) as inner2_
) as inner1_ where rownumber_ > 50 order by rownumber_;
I have run this myself using the IBMi Run SQL Script tool and no results are returned. However, if I just do the inner two selects:
select inner2_.*, rownumber() over(order by order of inner2_) as rownumber_ from (
select * from flxalll1 flxalll1x0_ where upper(flxalll1x0_.aoukey) like upper('%te%') fetch first 100 rows only
) as inner2_ ;
I get the expects list of result, though of course all of them and not just the last 50. I have done some more experimentation and discovered that (unsurprisingly) this works:
select * from (
select * from flxalll1
);
in that it lists all the records, but this:
select * from (
select * from (
select * from flxalll1
)
);
produces no records.
Obviously there is no sense in that but I'm wondering if there is a problem with DB2/400 in that it won't do a select with two nested sub-selects, or something like that, and is that the reason why my original query does not return any records?
Solving the problem could be tricky but for now at least I am just trying to work out where the problem lies.
I have now solved my problem by not using the (IBMi) logical as mentioned in my comment above but by allowing spring data jpa to do the UNION. I created an abstract super class for my 10 tables and changed their Java class declarations to extend it.
I am indebted to this post and to the answer by Patrice Blanchardie:
Union tables with spring data jpa

Not able to get Updatable and scrollable Result set in Oracle using Java

Class.forName("oracle.jdbc.driver.OracleDriver").newInstance();
conn=DriverManager.getConnection(URL,username,password);
String sql="select * from test where user_id='abc'";
stmt=conn.prepareStatement(sql,ResultSet.TYPE_SCROLL_SENSITIVE);
ResultSet rs=stmt.executeQuery();
rs.afterLast();
getting exception in this line, afterLast operation not allowed .
Reading from the oracle documentation:-
To produce a scroll-sensitive result set: A query cannot use SELECT * .
However, there is a workaround for this.
As a workaround for the SELECT * limitation, you can use table aliases, as shown in the following example:
SELECT t.* FROM TABLE t ...
Change your query to select test.* from test where user_id='abc'
or use specific column names to retrive instead of *.

SQL Firebird implementation in java/ IBSQL

so tried to put that SQL code into my java-aplication:
SELECT DISTINCT
StRzImRo.Rohstoff, StRo.Bezeichnung,
CAST (SUM(BwLsImAt.Lieferungen * StRzImRo.Menge * StAt.PROD__REZEPTURGEWICHT / Coalesce(StRz.PARM__BEZUGSGROESSE,1)) AS NUMERIC (9,3)) Rohstoffverbrauch_Gesamt FROM BwLsImAt
JOIN StAt ON (StAt.IntRowId = BwLsImAt.Artikel)
JOIN StRz ON (StRz.IntRowId = StAt.PROD__REZEPTUR)
JOIN StRzImRo ON (StRzImRo.Master = StRz.IntRowId)
JOIN StRo ON (StRzImRo.Rohstoff = StRo.IntRowId)
WHERE StAt.IntRowId > 0
GROUP BY StRzImRo.Rohstoff, StRo.Bezeichnung
-- GROUP BY StRzImRo.Rohstoff, StRzImRo.Menge, StAt.PROD__REZEPTURGEWICHT, Coalesce(StRz.PARM__BEZUGSGROESSE,1)
The code is fully funcional and tested in IBSQL but not working in my java-application.
My app does work properly with other code. I get this error:
org.firebirdsql.jdbc.FBSQLException: GDS Exception. 335544569. Dynamic SQL Error
SQL error code = -104
Token unknown - line 1, column 266
ON
I would be very happy if someone could help me with this problem. Thanks!
P.S.: Sorry for my bad language, but i´m not a native speaker
The error suggests there is an ON in an unexpected place in your query, and as the query itself looks fine, my guess is the problem is with the way you construct the query in your Java application. There might be some whitespace missing in your query.
My guess is that you have something like
query = "SELECT * " +
"FROM table1" +
"JOIN table2 ON " //.....
The missing whitespace will make the SQL:
SELECT * FROM table1JOIN table2 ON ....
For the parser, this is perfectly valid until it encounters the ON token, which triggers the error. Eg the parser identifies it is a SELECT with * (all) columns from table1JOIN with alias table2. During parsing the server doesn't check if the table actually exists, so it doesn't trip over the fact that table1JOIN doesn't exist. That is checked after parsing is successfully completed.

Categories