Passing String value to SQL bigint column - java

Given following Statment:
String query = "Select * from T_spareParts where SparePartPK IN (? )"
In my BackBean (JSF 2) I first iterate through all cars in table and build a String of all the cars currently selected (by picking each cars ID as primary key) so the final String before being passed to SQL could look like:
String finalString = " '1','2','3','4'";
And then :
this.prepareStatement= this.connection.prepareStatement(query);
this.prepareStatement.setString(1,finalString);
this.prepareStatement.executeQuery();
Exception thrown is:
Error converting data type nvarchar to bigint.
Now my understanding is that exception is due to SparePartPK is type bigint and we're passing a String .
But in SQL Server (2008) i can do :
Select * from T_spareParts where SparePartPK IN ('1','2','3','4')"
which returns results as expected. Why am i getting the exception and how can i correct the issue? (also feel free to comment if this isn't the best approach)
Update:
I've also tried to produce the finalString without single quotes which causes the same exception to be thrown :
String finalString = " 1,2,3,4";

You should put the numbers into an array (not a string), and use preparedStatement.setArray()

Thanks for the suggestions. Though as an alternative I created a StoredProcedure where it takes one parameter and inside the StoredProcedure i run the above Query in question formulating the IN section using the passed parameter .
So all above code still applies, The parameter passed to the storeDProcedure is one String separated by , without the single quotes.
Might not be the optimum answer but works quit well :) .

Related

How to invoke stored function in java of PostgreSQL database with JDBCTemplate

I have a stored function that takes below arguments in database.
CREATE OR REPLACE FUNCTION
public.abc(
id integer,
title text,
description text,
valid_until_date timestamp with time zone,
user_is_ext boolean,
remarks text)
{
//statements
}
I need to invoke this stored function. I am able to invoke directly in database using below query:
select "abc" (0,'title','description','2010-01-01 00:00:00+01',false,'text')
However i am not able to invoke using JDBC template in my SpringBoot application.
String sql="select \"abc\" (?,?,?,?,?,?)";
List<Integer> ids=jdbcTemplate.query(sql,new Object[]{id,myObj.getTitle(), myObj.getDescription(), myObj.getValidDate(), myObj.isUserExt(), ,myObj.getRemarks()},new BeanPropertyRowMapper(Integer.class));
Can someone help me to figure out what is it that I am missing?
i get "The column index is out of range:" error.
I tried using "update" instead of "query"
int ind=jdbcTemplate.update(sql, id,myObj.getTitle(), myObj.getDescription(), myObj.getValidUntilDate(), myObj.isUserExt(), myObj.getRemarks());
then i get following error
""2017-07-10 14:51:16 [http-bio-8080-exec-60] ERROR c.s.k.l.exceptions.ExceptionHandlers --- A result was returned when none was expected. –
tried using SimpleJDBC call as mentioned on the comment. getting below error while passing timestamp as a parameter in SQLParameter object
""2017-07-10 16:18:16 [http-bio-8080-exec-97] ERROR c.s.k.l.exceptions.ExceptionHandlers --- Bad value for type timestamp : org.springframework.jdbc.core.SqlParameter#3a4cbd06
Finally i resolved it!!
In my case I'm trying to invoke a stored function that returns an integer value. please find the code snippet below.
String sql="select * from \"stored_function_name\" (?,?,?,?,?,?,?,?,?)";
Integer result=jdbcTemplate.queryForObject(sql,Integer.class, new Object[] {all input parameters separated by coma});
Similarly we can use other variants of query.
Please make sure the parameters that you pass to function should have same datatype as in postgres database. If its a timestamp in db and you have date as string, you can convert it to timestamp using below code
Timestamp.valueOf("date_string in yyyy-mm-dd hh:mm:ss format")
Thank you everyone!!

How to config OpenJPA encoding?

I'm having an issue with OpenJPA. I used it to persist values in MySQL DB. Amoung these values, there's a String value that has a spanish character (á). The data was persisted correctly, with the special character being shown perfectly in the DB.
The problem comes when, within my Java program, I try to query the DB with one of the parameters having this special character. Here's an example:
private static final String getPerdiodoEstadoAfiliacionParaOS =
"SELECT x FROM PeriodoAfiliacion x WHERE " +
"x.obraSocial=?1 " +
"AND x.tipoPeriodoAfiliacion LIKE ?2";
public static List<PeriodoAfiliacion> getPerdiodoEstadoAfiliacionParaOS(EntityManager em, ObraSocial os, String periodoABuscar) {
if(os==null) return new ArrayList<PeriodoAfiliacion>();
Query query = em.createQuery(getPerdiodoEstadoAfiliacionParaOS);
query.setParameter(1, os);
query.setParameter(2, periodoABuscar);
return query.getResultList();
}
So, parameter number 2 (the one shown as ?2), it's a string with a special character in it.
The query comes back empty when there's actually data.
I know the problem is the special character, because if I pass as a parameter another String that doesn't have the special character in it, the query comes back with results as expected.
So, I don't know what the problem is really. I guess it has something to do with the way the parameter is passed from OpenJPA to the DB engine.
Do you guys have suggestions??

not passing List of String as single parameters inside preparedStatement.setObject()

I want to pass a List of String coming from request parameter to the preparedStatement.setObject() as a single parameter.Here I have coverted list of Objects to a single String.
So while passing this converted String to setObject method it is converting ' to \'.
So my query is like :
select * from category where category IN (?)
for (int counter = 0; (!sqlParams.isEmpty()) && counter < sqlParams.size(); counter++) {
System.out.println(sqlParams.get(counter));
stmt.setObject(counter + 1, sqlParams.get(counter));
System.out.println(stmt.toString());
}
here sqlParams.get(counter) is giving following value to me.
'Adult', 'Classic', 'Fantasy', 'Mystery'
but wen i am using stmt.setObject(), and printing the values of stmt, it is showing following value :
'\'Adult\', \'Classic\', \'Fantasy\', \'Mystery\''
So at query formation is something like this :
SELECT * FROM mytable WHERE category IN ('Adult\', \'Classic\', \'Fantasy\', \'Mistry\'');
There are other ways to solve these approach too, such as passing individual String and then query execution for each individual String.but It will increase time complexity for my code.
Can anyone Suggest me the solution for this?
JDBC prepared statements cannot be used when the number of parameters is variable, like here. The ? in the query is expanded into a single value, not to several separated by commas.
What you can do is construct an sql with the appropriate number of ?s and then set each parameter in a loop.

Issue with COALESCE in DB2 and Jasper Reports

I am having a query wherein I am fetching out sum of a column from a table formed through sub query.
Something in the lines:
select temp.mySum as MySum from (select sum(myColumn) from mySchema.myTable) temp;
However, I don't want MySum to be null when temp.mySum is null. Instead I want MySum to carry string 'value not available' when temp.mySum is null.
Thus I tried to use coalesce in the below manner:
select coalesce(temp.mySum, 'value not available') as MySum from (select sum(myColumn) from mySchema.myTable) temp;
However above query is throwing error message:
Message: The data type, length or value of argument "2" of routine "SYSIBM.COALESCE" is incorrect.
This message is because of datatype incompatibility between argument 1 and 2 of coalesce function as mentioned in the first answer below.
However, I am directly using this query in Jasper to send values to Excel sheet report:
hashmap.put("myQuery", this.myQuery);
JasperReport jasperReportOne = JasperCompileManager.compileReport(this.reportJRXML);
JasperPrint jasperPrintBranchCd = JasperFillManager.fillReport(jasperReportOne , hashmap, con);
jprintList.add(jasperPrintOne);
JRXlsExporter exporterXLS = new JRXlsExporter();
exporterXLS.setParameter(JRExporterParameter.JASPER_PRINT_LIST, jprintList);
exporterXLS.exportReport();
In the excel sheet, I am getting value as null when the value is not available. I want to show 'value unavailable' in the report.
How could this be achieved ?
Thanks for reading!
The arguments to coalesce must be compatible. That's not the case if the first is numeric (as mySum probably is) and the second is a string.
For example, the following PubLib doco has a table indicating compatibility between various types, at least for the DB2 I work with (the mainframe one) - no doubt there are similar restrictions for the iSeries and LUW variants as well.
You can try something like coalesce(temp.mySum, 0) instead or convert the first argument to a string with something like char(). Either of those should work since they make the two arguments compatible.

JAVA: NamedQuery String problem

Hello guys I am having some problems with exact matches while doing a NamedQuery.
I am currently using something like this:
#NamedQuery(name = MyClass.GET_ENTRY_BY_NAME, query = "select e from Entry e where e.name =:"+ Entry.NAME )
...
Query query = em.createNamedQuery(MyClass.GET_ENTRY_BY_NAME);
query.setParameter(Entry.NAME, myEntry.getName());
It works for most cases, however I noticed that in case the user pass the file name with an space at the end, the namedQuery ignores that character. For example:
Query query = em.createNamedQuery(MyClass.GET_ENTRY_BY_NAME);
query.setParameter(Entry.NAME, myEntry.getName()+ " ");
Will return the same result as the query before. Bypassing my 'valid entry' validation. In other words I'd like the query to return no entry at all and treat the error later on.
One workaround I could think of, is to put single quotes surrounding my parameter in the namedQuery, like this:
#NamedQuery(name = MyClass.GET_ENTRY_BY_NAME, query = "select e from entry e where e.name =':"+ Entry.NAME "'")
However it will trash my code in case the String contains single quotes in it...
Any ideas guys?
I guess this happens because your database field is declared as CHAR(...), and therefore stored values are padded with whitespaces which are not taken into account by = operation.
So, you may either declare your database field as VARCHAR(...) or use a built-in trim function:
query = "select e from Entry e where trim(trailing from e.name) =:"+ Entry.NAME
I did some research in JPA and found out that it does some automatic trimming for CHARs, I am not sure if this behaves the same with Strings, but since it is happening to me... I believe so. The only way to bypass it is by setting some attribute within the session DatabaseLogin object (see http://www.eclipse.org/eclipselink/api/1.1/org/eclipse/persistence/sessions/DatabaseLogin.html#setShouldTrimStrings) .
Well I didn't want to be messing up with the session properties so I decided to make some sort of check and throwing the same exception as the NoResultException catch does in my code.
I basically took the result from the database and compared the field with the String I used:
query.setParameter(Entry.NAME, myEntry.getName());
...
if(!StringUtils.equals(result.getName(), myEntry.getName()){
do a cool throw just like NoResultException Catch
}
I also had to include the Trim function axtavt! This is just to make sure that if the database has a column with trailing spaces and it matches the parameter given by the user, it will be included as a valid answer. For example:
Database entry: Name = "Flavio " - Trimmed with Function = "Flavio".
Parameter passed: Name = "Flavio " - Trimmed by JPA automatic function = "Flavio".
If it isnt trimmed at all it will just Compare "Flavio " with "Flavio", returning NoResult when it was supposed to return that Entry.
Nasty workaround, but as long as there is no other way to stop the auto-trimming we will have to just make use of this sort of things.
Thanks for all the other answers!!

Categories

Resources