9

I have created a native query with interval. The query works fine when i hard code day in query:

@Query(value="select * from orders where created_date  < clock_timestamp() - interval ' 5 days'",nativeQuery=true)

But when i provide data with @Param like this:

@Query(value="select * from orders where created_date  < clock_timestamp() - interval :day 'days'",nativeQuery=true)
List<Order> getData(@Param("day") String day)

I got this error:

Caused by: org.postgresql.util.PSQLException: ERROR: syntax error at or near "$1"

Ajit Soman
  • 3,926
  • 3
  • 22
  • 41

2 Answers2

19

You can't provide a value for an interval like that. You need to multiple the parameter value with your interval base unit:

"select * from orders 
where created_date  < clock_timestamp() - (interval '1' day) * :days"

As you are dealing with days, you can simplify that to:

"select * from orders 
where created_date  < clock_timestamp() - :days"

Another option is the make_interval() function. You can pass multiple parameters for different units.

"select * from orders 
where created_date  < clock_timestamp() - make_interval(days => :days)"

The notation days => ... is a named parameter for a function call. If the variable represents hours, you could use make_interval(hours => ..)

6

One solution is provided in this entry Spring Boot Query annotation with nativeQuery doesn't work in Postgresql

Basically:

@Query(value="select * from orders where created_date  < clock_timestamp() - ( :toTime )\\:\\:interval",nativeQuery=true)

'toTime' is a Param from your repository and could be days, hour, minute... etc(review interval doc in Postgres) @Param("toTime") String toTime

Sergio Gonzalez
  • 215
  • 1
  • 4
  • 11
  • This is what solved my issue - escaping the double colons since JPA was interpreting that as substitution variables – Phillip Nov 12 '19 at 17:29
  • This works in a Query annotation but does not work in a Formula annotation. In the Formula annotation, I ended up writing it as `make_interval(0,0,0,1)` to specify a 1 day interval. – Philippe Sep 29 '20 at 17:27
  • @sergio could you please tell me how i can pass my sql correctly in the query annotation : DELETE FROM TABLE WHERE my_column < (NOW() - INTERVAL '30 minutes') and i want to pass '30 minutes' as a param in my java method – James Nov 08 '22 at 14:54