error syntax error at or near ":" for split_part () of createNativeQuery in spring boot for postgresql - postgresql

I'm getting SQL exception while executing the query which contains
split_part() method as split_part(value::TEXT,':', 1).
String queryStr = " select split_part(value::TEXT,':', 1) from table";
Query query = entityManager.createNativeQuery(queryStr);
List results = query.getResultList();
ERROR 2020-02-10 14:54:37,926 [http-nio-7070-exec-1] 142 - ERROR: syntax error at or near ":"
Position: 855

Your obfuscation layer probably chokes on the :: operator. Use the cast() operator instead:
String queryStr = " select split_part(cast(value as text),':', 1) from table";
But why do you think you need the cast to begin with? If you are storing : characters that column, it is most probably a text (or varchar) column anyway and you don't need a cast at all.

Related

Springboot JPA Cast numeric substring to string

I have a JPA/Springboot application backed by a Postgres database. I need to get a records that is equal to a substring passed back to the server.
For example:
Select * from dp1_attachments where TRIM(RIGHT(dp1_submit_date_dp1_number::text, 5)) ='00007'
This query works in PgAdmin, but not in the JPA #Query statement.
#Query("SELECT a.attachmentsFolder as attachmentsFolder, a.attachmentNumber as attachmentNumber, a.attachmentName as attachmentName, a.dp1SubmitDateDp1Number as dp1SubmitDateDp1Number,a.attachmentType as attachmentType, a.attachmentDate as attachmentDate, a.attachmentBy as attachmentBy "
+ "FROM DP1Attachments a WHERE TRIM(SUBSTRING(a.dp1SubmitDateDp1Number::text, 5 )) = :dp1Number")
I've also tried CASTing the parameter like this:
#Query("SELECT a.attachmentsFolder as attachmentsFolder, a.attachmentNumber as attachmentNumber, a.attachmentName as attachmentName, a.dp1SubmitDateDp1Number as dp1SubmitDateDp1Number,a.attachmentType as attachmentType, a.attachmentDate as attachmentDate, a.attachmentBy as attachmentBy "
+ "FROM DP1Attachments a WHERE TRIM(SUBSTRING(CAST(a.dp1SubmitDateDp1Number as string, 5 ))) = :dp1Number")
but the application won't even run, and returns an error that the query isn't valid.
If I make no attempt to cast it, I get an error that function pg_catalog.substring(numeric, integer) does not exist
UPDATE
I've also tried creating a native query instead but that also doesn't seem to work.
List<DP1AttachmentsProjection> results = em.createNativeQuery("Select * FROM dp1_attachments WHERE TRIM(RIGHT(CAST(dp1_submit_date_dp1_number as varchar),5)) =" + dp1Number).getResultList();
In place of varchar I have also tried string and text.
Errors come back similar to ERROR: operator does not exist: text = integer. Its like the CAST is being ignored and I'm not sure why.
I also tried the following as a native query:
em.createNativeQuery("Select * FROM dp1_attachments WHERE TRIM(RIGHT(dp1_submit_date_dp1_number::varchar),5)) =" + dp1Number).getResultList();
and get ERROR: syntax error at or near ":"
FINAL SOLUTION
Thanks to #Nenad J I altered the query to get the final working solution:
#Query(value = "SELECT a.attachments_Folder as attachmentsFolder, a.attachment_Number as attachmentNumber, a.attachment_Name as attachmentName, a.dp1_Submit_Date_Dp1_Number as dp1SubmitDateDp1Number,a.attachment_Type as attachmentType, a.attachment_Date as attachmentDate, a.attachment_By as attachmentBy FROM DP1_Attachments a WHERE TRIM(RIGHT(CAST(a.dp1_Submit_Date_Dp1_Number as varchar ), 5 )) = :dp1Number", nativeQuery = true)"
Default substring returns a string, so substring(integer data,5) returns a string. Thus no need for the cast.
#Query("SELECT * FROM DP1Attachments a WHERE TRIM(SUBSTRING(a.dp1SubmitDateDp1Number, 5)) = :dp1Number")
But I recommend in this case use native query like this:
Put this code in your attachment repository.
#Query(value="SELECT * FROM DP1Attachments AS a WHERE TRIM(SUBSTRING(a.dp1SubmitDateDp1Number, 5 )) = :dp1Number", nativeQuery=true)
Be careful with the column's name.

How to use CAST function with JPQL Query

I am trying to use CAST function in JPQL query for converting data type from Integer to String. But I am getting QuerySyntaxException.
JPQL Query
#Query("select a from Alerts as a "
+ "Inner Join RoomTransfer as rt ON a.salertActionData= cast (rt.nTransId character varying)"
+ " where a.nalertId=?1")
public List<Alerts> transferedDetailsByAlertId(Integer nalert_id );
Error
java.lang.IllegalArgumentException: org.hibernate.hql.internal.ast.QuerySyntaxException: expecting CLOSE, found 'varying' near line 1
Can any one please tell me what I am doing wrong?
Write CAST (rt.nTransId AS string)
See:
http://docs.jboss.org/hibernate/orm/5.2/userguide/html_single/Hibernate_User_Guide.html#hql-functions
http://docs.jboss.org/hibernate/orm/5.2/userguide/html_single/Hibernate_User_Guide.html#basic-provided

PostgreSQL {call Update Set ...} getting "syntax error at or near SET"

I'm changing queries from an Oracle Database to PostgreSQL, and in this query I am getting this error:
ERROR: syntax error at or near "SET"
the query is:
{call UPDATE alarm_instance SET last_update_time=default, wait_expire_time=null, core_number=nextval(SEQ_ALRM_NUMBR)
where wait_time <= current_date RETURNING alarm_instance_id bulk collect INTO ?}
I am using JDBC to connect to the database and here is the call code
try (CallableStatement cs = super.prepareCall_(query)) {
cs.registerOutParameter(1, Types.ARRAY);
cs.execute();
...
I have taken a long look at Postgres documentation and cannot find what is wrong and didn't find any answer to this specific situation
An UPDATE statement can't be executed with a CallableStatement. A CallableStatement is essentially only intended to call stored procedures. In case of Oracle that includes anonymous PL/SQL blocks.
And bulk collect is invalid in Postgres to begin with.
It seems you want something like this:
String sql =
"UPDATE alarm_instance " +
" SET last_update_time=default, " +
" wait_expire_time=null, "
" core_number=nextval('SEQ_ALRM_NUMBR') " +
" where wait_time <= current_date RETURNING alarm_instance_id";
Statement stmt = connection.createStatement();
stmt.execute(sql);
int rowsUpdated = stmt.getUpdateCount();
ResultSet rs = stmt.getResultSet();
while (rs.next() {
// do something with the returned IDs
}

Exception occurs for hash character in Dollar quote with JPA

I am using Dollar quote (i.e. $xx$) for my query and getting Exception when the input has a hash character(#) inside.
select * from tbl_abc where col_x = $xx$#$xx$
^
The Exception is:
Internal Exception: org.postgresql.util.PSQLException: The column index is out of range: 1, number of columns: 0.
Error Code: 0
Call: select * from tbl_abc where col_x = $xx$?
bind => [1 parameter bound]
I can see there a ? character in the error message, but I didn't have that in my query. Here is my java code:
String query = "select * from tbl_abc where col_x = $xx$#$xx$";
Query nativeQuery = em.createNativeQuery(query, Abc.class);
List<Abc> abcList = nativeQuery.getResultList();
FYI: it works smoothly when I use '#' instead of $xx$#$xx$. Also my query runs nicely from the postgres console.
How can I escape that # character for Dollar quote from JPA?
I am using Java with Eclipselink and the database is Postgres.

How to use AND operator in statement

I am using JDBC in JSP with PostGreSQL.
I want to read all values of a row with the given titel and interpret from a text field but the AND operator doesn't work.
// some code
stmt = conn.createStatement();
res = stmt.executeQuery(
"SELECT * " +
"FROM album " +
"WHERE interpret = ? AND titel = ? " +
"ORDER BY interpret, titel ASC "
);
//... closte statements, etc.
Not I get a syntax exception for AND.
Do you guys have any advices why?
You cannot use bind variables in a statement created with createStatement.
PreparedStatement is what you should be working with.
Use:
stmt = conn.prepareStatement();
stmt.setString(1, interpretValue); //set the value for the first parameter to interpretValue
stmt.setString(2, titleValue); //second parameter
A PreparedStatement is the preferred way of executing SQL statements because the statement is precompiled. This can be more efficient than a Statement, specially if the same query is executed multiple times.