No Value specified for parameter 2 - java

I am getting this error when trying to run my Spring boot.
java.sql.SQLException: No value specified for parameter 2
My code is this:
public UserTemp findHistoryByID(Integer Patient_Number) {
String sql = "select Col1\n" +
"from (\n" +
" select Past_Diagnoses_1 as Col1\n" +
" from patienthistory\n" +
" where Patient_Number = ?\n" +
" union\n" +
" select Past_Diagnoses_2 as Col1\n" +
" from patienthistory" +
" where Patient_Number = ?" +
" ) as T;";
return jdbcTemplate.queryForObject(sql, new Object[]{Patient_Number}, (rs, rowNum) ->
new UserTemp(
rs.getString("Col1")
));
}

As in the comments, you are having 2 placeholders in the SQL query. So you have to pass patient_number 2 times.
Coming to your second question, it depends on your requirement.
If you need a single result, you need to fix it on the DB side as it's a data issue or the query used is not proper.
If more than one result is allowed, you can use jdbcTemplate.queryForList() instead of jdbcTemplate.queryForObject(). And change the return type of findHistoryByID() to List<Map<String,Object>> and all callers of this function.
Note: Here key for each Map in List is column names returned from DB.
More information on jdbcTemplate.queryForList() is in official documentation

Related

How to compare LocalDateTime values in JPQL query?

It is necessary to select dataset using JPQL query with optional condition - comparing the field value (LocalDateTime type) with a user-specified parameter (also LocalDateTime type).
First I made a well working code:
return entityManager.createQuery(
"SELECT new com.******.*******.*******.****.models.dto.SomeDto " +
"(s.id, " +
"s.userId) " +
"s.persistDate) " +
"FROM Some s WHERE s.userId = :userId
AND s.persistDate >= :userDateTime", SomeDTO.class)
.setParameter("userId", userId)
.setParameter("userDateTime", userDateTime)
This code works but there is one problem:
this condition may exist or may not exist - dependent on app logic. Therefore, there is a need not to use injection using .setParameter (for this condition), but to form a string (which may be empty) depending on the logic and then add to the request:
String extraCondition = (userDateString.equals("false")) ? "" :
"AND s.persistDateTime >= " + userDateString;
return entityManager.createQuery(
"SELECT new com.******.*******.*******.****.models.dto.SomeDto " +
"(s.id, " +
"s.userId) " +
"s.persistDate) " +
"FROM Some s WHERE s.userId = :userId " + extraCondition, SomeDTO.class)
.setParameter("userId", userId)
But the problem is that no matter how I tried to format the userDateString variable, I get an Internal Server Error.I even tried using just a text string instead of variable (tried with different formatting):
String extraCondition = (userDateString.equals("false")) ? "" :
"AND s.persistDateTime >= 2023-01-27T23:30:50";
But the result is also bad - Internal Server Error.
I also tried using the .isAfter method instead of the ">=" operator, but that didn't help either.
How to inject LocalDateTime values comparing into query as String?
even if the date string may or may not be necesssary, you can (and should!) still use parameter injection, not formatted values.
Basically, your code should look like this:
String queryStr = ....;
boolean someCondition = <expensive_test_here>;
if(someCondition) {
queryStr += " AND s.persistDate >= :userDateTime";
}
Query q = em.createQuery(queryStr).setParameter("userId", userId);
if(someCondition) {
q.setParameter("userDateTime", userDateTime);
}

Jpa native query doesnt work with group by case/when statement with binding values

Iam trying to use Jpa repository to get data from my sql server using a native query
This is a simple call from my service
repo.testData("h3","h3");
This is my repository query.
Select statement can read the binding variable :level but group by is unable to read it.
#Query(value="SELECT sum(pos.total_weekly_sales) as curr_yr_sales, sum(pos.total_weekly_qty) as curr_yr_qty, pos.vendor_nbr,pos.gmm_id,\n" +
"case \n" +
"when :level = 'h3' then pos.category_id\n" +
"else 0\n" +
"end category_id\n" +
"from dbo.agg_sams_data pos\n" +
"join dbo.calendar_dim cal on pos.wm_year_wk_nbr = cal.wm_year_wk_nbr\n" +
"WHERE \n" +
"cal.calendar_date BETWEEN '2019-09-11' and '2020-09-09'\n" +
"and pos.vendor_nbr = 68494\n" +
"and pos.gmm_id = 45\n" +
"and (:h3Flag = 'N' or pos.category_id = 52)\n" +
"GROUP by pos.vendor_nbr,pos.gmm_id,\n" +
"case \n" +
"when :level='h3' then pos.category_id\n" +
"else 0\n" +
"end",nativeQuery = true)
List<List<Double>> testData(String level,String h3Flag);
And i get the following error
com.microsoft.sqlserver.jdbc.SQLServerException: Column 'dbo.agg_sams_data.category_id' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
If i pass the hardcoded value in the group by clause it works fine(as below)
"GROUP by pos.vendor_nbr,pos.gmm_id,\n" +
"case \n" +
"when 'h3'='h3' then pos.category_id\n"
You should try putting pos.category_id into the group by instead of the whole case when statement. The problem is, that SQL Server can't be sure that the parameter in both cases will have the same value so the expressions could be different.

Couchbase parameterized query with numeric values

I'm trying to add numeric values to parameterized AnalyticsQuery but keep getting errors when the query runs. The java creating the query looks like this:
private ParameterizedAnalyticsQuery aggregateQuery(String userId, Long from, Long to) {
return AnalyticsQuery.parameterized(
"select d.field1,"
+ " d.field2"
+ " from data d"
+ " where d.userId = $userId"
+ " and d.timestamp between $from and $to",
JsonObject.create()
.put("userId", userId)
.put("from", from)
.put("to", to)
);
}
When the query is run the following error is returned:
<< Encountered \"from\" at column 213. ","code":24000}]
If I change the query to the following then it works and returns rows:
return AnalyticsQuery.parameterized(
"select d.field1,"
+ " d.field2"
+ " from data d"
+ " where d.userId = $userId"
+ " and d.timestamp between " + from
+ " and " + to,
JsonObject.create()
.put("userId", userId)
);
Why is there a problem when the parameters are not Strings? Is there a way to use parameterized queries with numeric values?
FROM and TO are reserved keywords in N1QL for Analytics and therefore must be put in backquotes when used as parameter names:
... and d.timestamp between $`from` and $`to`
For a list of all reserved keywords please see:
https://docs.couchbase.com/server/current/analytics/appendix_1_keywords.html

PostgreSQL IF statement won't accept parameters

I'm trying to use PostgreSQL IF sentence and I use MapSqlParametersSource to pass parameter to the SQL query. Interesting thing happens that if I pass a parameter to IF condition subquery it won't accept (interpret it properly) it, but if I define value in subquery then it will give me the results. So what I mean is this:
This works
MapSqlParameterSource params = new MapSqlParameterSource();
params.addValue("recurr", true);
String sql = "DO " +
"$do$ " +
"BEGIN " +
"IF (SELECT f.recurring_till FROM FINANCE_ENTITY f WHERE f.recurring = true) THEN SELECT amount, name FROM FINANCE_ENTITY; " +
"END IF; " +
"END " +
"$do$";
getNamedParameterJdbcTemplate().query(sql, params, BeanPropertyRowMapper.newInstance(FinanceEntity.class));
This return me results successfully.
This won't work
MapSqlParameterSource params = new MapSqlParameterSource();
params.addValue("recurr", true);
String sql = "DO " +
"$do$ " +
"BEGIN " +
"IF (SELECT f.recurring_till FROM FINANCE_ENTITY f WHERE f.recurring = :recurr) THEN SELECT amount, name FROM FINANCE_ENTITY; " +
"END IF; " +
"END " +
"$do$";
getNamedParameterJdbcTemplate().query(sql, params, BeanPropertyRowMapper.newInstance(FinanceEntity.class));
This will give me always following error:
org.postgresql.util.PSQLException: The column index is out of range: 1, number of columns: 0.
My question is why I can't pass a parameter to my subquery using MapSqlParameterSource?
I use PostgreSQL 9.3.
The problems with parameter passing aside (so this does not directly answer your question) you don't need either a DO statement or an IF for this. A simple SELECT does the job:
SELECT amount, name
FROM FINANCE_ENTITY
WHERE EXISTS (
SELECT 1
FROM FINANCE_ENTITY
WHERE recurring = $1
AND recurring_till
);
More importantly, you cannot return rows from a DO statement at all. So your claim "This return me results successfully" is ... a surprise to say the least. Because that's impossible:
How to perform a select query in a DO block?
PostgreSQL Function PERFORM

fetch value from SQL query list

So i just wrote down this SQL query and i am trying to capture the value of rest_id in query.list(). However, this is giving the value as [1] . I want just 1 without the braces. How do i do it? Please check the code below for reference:
String sql1 = "select rest_id from rest_details where rest_name = '" + nameclicked + "' and rest_location = '" +locclicked + "'" ;
SQLQuery query1 = session.createSQLQuery(sql1);
System.out.println("sql1 " + query1.list());
Use below code to get the element inside list:
System.out.println("sql1 " + query1.list().get(0));
This always returns only the first element from the list.
Replace
System.out.println("sql1 " + query1.list());
By :
for(String id : query1.list() ) System.out.println("sql1 " + id);

Categories

Resources