SQLServerCallableStatement not returing the result set - java

I am trying out a simple test and so I have a simple stored procedure. It selects rows from a table
CREATE PROCEDURE [dbo].[Test_SQL_Connect]
as
BEGIN
SET NOCOUNT ON
select * from [dbo].[Test_Sqlconnector]
END
When I run exec [dbo].[Test_SQL_Connect] ..the output is
TagName TagValue Timestamp TagStatus
tag1 value1 2017-01-31 19:09:43.7570000 1
In Java, I have the following code(connection has been created earlier)
SQLServerCallableStatement cStatement =
(SQLServerCallableStatement)connection.prepareCall("{call dbo.Test_SQL_Connect}");
cStatement.execute();
After execution the value of cStatement.getUpdateCount() = -1 .
Would anyone know why the updatecount is -1 even though 1 record is returned?

This is the expected result of Statement.getUpdateCount()
Retrieves the current result as an update count; if the result is a
ResultSet object or there are no more results, -1 is returned.
This method should be called only once per result.
Also have a look at the javadoc of PreparedStatement.execute().

Related

Neo4j Apoc Case When get result summary in java

Hey I'm currently writing a Java application that accesses NEO4J via Spring Neo4J Driver.
I have a couple of nodes with arrays. No I'm trying to write an cypher Query that deletes an Element from an array of a matched node. If the element was the last one i would love to delete the complete node. To achive this I'm using apoc.do.when. You can find a simplified version of my query below.
MATCH (n:NODE) WHERE "Peter" IN n.NAMES
CALL apoc.do.when(size(n.NAMES) > 1, 'SET n.NAMES = [x IN n.NAMES WHERE x <> "Peter"]', 'DETACH DELETE n') YIELD value
RETURN value
My query is overall working fine, but I don't get the Result summary back anymore in my Java application.
I'm calling the query the following way:
ResultSummary output = driver.session().run(query.withParameters(params)).consume();
I know that the query is executed and deleting a node. I validated that by Neo4J browser, but the result summary says:
serverInfo=InternalServerInfo{address='localhost:7687', version='Neo4j/3.5.17'}, databaseInfo=InternalDatabaseInfo{name='null'}, queryType=READ_WRITE, counters=null, plan=null, profile=null, notifications=[], resultAvailableAfter=143, resultConsumedAfter=1}
Updates: 0
Delete: 0
Therefore i can not validate from my Javacode if the operation was successful. I assume that apoc.do.when does not promote the result summary from the query correctly. Is there anyway to fix this or do i need to validate this with a second query?
You can modify the Cypher query to return a result that indicates whether an update or deletion occurred. For example:
MATCH (n:NODE) WHERE "Peter" IN n.NAMES
CALL apoc.do.when(
size(n.NAMES) > 1,
'SET n.NAMES = [x IN n.NAMES WHERE x <> "Peter"] RETURN "updated" AS res',
'DETACH DELETE n RETURN "deleted" AS res') YIELD value
RETURN value.res AS res
Then your Java client can iterate through (or stream) the resulting records and count the number of updates and deletions.

JPA calling stored procedure with argument

I have this procedure in my postgreSQL database:
CREATE OR REPLACE FUNCTION getItemsForCategory(categoryId integer)
RETURNS SETOF ITEM AS $_$
DECLARE
result ITEM;
BEGIN
FOR result IN SELECT *
FROM item it
JOIN item_category itcat ON it.id = itcat.item_id WHERE itcat.category_id = categoryId LOOP
RETURN NEXT result;
END LOOP;
END; $_$ LANGUAGE 'plpgsql';
which works excellent using terminal, but I have trouble with calling it using JPA. Here is my code snippet(4 is value of argument cateforyId):
transactions.begin();
final StoredProcedureQuery storedProcedureQuery = entityManager.createStoredProcedureQuery("getItemsForCategory");
storedProcedureQuery.setParameter(1,4).execute();
final List<ItemEntity> itemEntityList = (List<ItemEntity>) storedProcedureQuery.getResultList();
transactions.commit();
after running code above I receive this error:
Exception in thread "main" java.lang.IllegalArgumentException:
You have attempted to set a parameter at position 1 which does not exist in this query string getItemsForCategory
Has anyone some idea how to set the value of argument correctly? I've also tried to set parameter using 0 instead of 1, calling setParameter with others datatypes of arguments (String,Object) but everytime I am receiving familiar kind of error like the one, which is shown there. Thank you very much
You need to register your parameters, before setting values.
spq.registerStoredProcedureParameter("categoryId", int.class, ParameterMode.IN);
See this link.

Why is this Java query failing? returning 0 when there are results

Hi can anyone tell me why this java query is failing?
Query q = entityManager.createNativeQuery("SELECT m.* FROM MdmAudit m WHERE m.correlationID = :correlationId AND m.verb = :verb", MdmAuditDAO.class);
//Query q = entityManager.createNamedQuery("MdmAuditDAO.GetData");
q.setParameter("correlationId", resp.getHeader().getCorrelationID());
q.setParameter("verb", resp.getHeader().getVerb());
long result = (long) q.getFirstResult();
The namedQuery:
#NamedQuery( name="MdmAuditDAO.GetData", query="SELECT m FROM MdmAuditDAO m WHERE m.correlationId = :correlationId AND m.verb = :verb")
public class MdmAuditDAO implements Serializable {
I have getters and setter in my MdmAuditDAO class, and I have checked the naming of the variables, and they are identical as in the NamedQuery, so the problem does not lie there.
My problem is that I have three entries in my database, I should at least get one answer back but I get 0 in my result.
MdmAuditDAO is defined in my persistence.xml and in my ehcache.xml. So why is it that the result I get returned is 0? I have also tried to get an object returned or a list of objects, and it is the same result, nothing gets returned, but when I run my query in my mssql database I get results see picture below. It has nothing to do with the m.* I aslo get results when I use that in my SELECT statement.
EDIT 1: This is what I get from my hibernate log, and I do not know how to read this?
Hibernate:
select
mdmauditda0_.id as id1_7_,
mdmauditda0_.correlationID as correlat2_7_,
mdmauditda0_.messageID as messageI3_7_,
mdmauditda0_.meter_no as meter_no4_7_,
mdmauditda0_.noun as noun5_7_,
mdmauditda0_.payload as payload6_7_,
mdmauditda0_.source as source7_7_,
mdmauditda0_.subtype as subtype8_7_,
mdmauditda0_.time as time9_7_,
mdmauditda0_.verb as verb10_7_
from
MdmAudit mdmauditda0_
where
mdmauditda0_.correlationID=?
Anything I have to set, to get more information? I am using the following jars
And my java version is 1.7.0_79.
I found the solution http://www.objectdb.com/api/java/jpa/Query/getFirstResult returns the position of the first element, but I was a bit confused by the phrase
Returns 0 if setFirstResult was not applied to the query object.
Could not get my head around it to make any sense of it.
My solution now is that I just return a list of objects
Query q = entityManager.createNativeQuery("SELECT m.* FROM MdmAudit m WHERE m.correlationId = :correlationId AND verb = :verb", MdmAuditDAO.class);
//Query q = entityManager.createNamedQuery("MdmAuditDAO.GetData");
q.setParameter("correlationId", resp.getHeader().getCorrelationID());
q.setParameter("verb", resp.getHeader().getVerb());
List<MdmAuditDAO> mdmAuditList = q.getResultList();
And then it works fine and I get results. So instead of the the result == 0 check I am doing later in my code I just do a NULL and isEmpty() check instead().
Side note: I have not tried to delete entries and then see what the result would be then in the q.getFirstResult() call but that would be a possibility and see what i get returned and then check on that value, properbly null?

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.

Categories

Resources