I am trying the following code:
public class StoredProcedureParam
{
private String m_sType;
private String m_sValue;
private String m_sParamName;
public StoredProcedureParam(String a_sParamName, String a_sType, String a_sValue)
{
m_sType = a_sType;
m_sValue = a_sValue;
m_sParamName = a_sParamName;
}
}
ArrayList<StoredProcedureParam> spmArr = new ArrayList<StoredProcedureParam>();
spmArr.add(new StoredProcedureParam("sBridgePhone", "NString", "value1"));
spmArr.add(new StoredProcedureParam("sCallerPaidTelNumber", "NString", "value2"));
spmArr.add(new StoredProcedureParam("sTollFreeTelNumber", "NString", "default"));
spmArr.add(new StoredProcedureParam("sParticipantAccessCode", "NString", "value3"));
spmArr.add(new StoredProcedureParam("sHostPassword", "NString", "value4"));
spmArr.add(new StoredProcedureParam("tNowUtc", "output", "timestamp"));
spmArr.add(new StoredProcedureParam("nStatusCode", "output", "Int"));
if (!m_jdbcWrapper.callStoredProcedure("{call spAddConference(?,?,?,?,?,?,?)}", spmArr)) {
System.out.println("callAddConferenceSp - Failed to execute");
return "";
}
public boolean callStoredProcedure(String a_sStoredProcedure, ArrayList<StoredProcedureParam> a_ParamList)
{
try
{
connect();
m_cStatement = m_Connection.prepareCall(a_sStoredProcedure,
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
registerSpParams(a_ParamList);
m_cStatement.execute();
}
catch (SQLException ex)
{
ex.printStackTrace();
return false;
}
finally
{
try
{
m_cStatement.close();
System.out.println("JDBCWrapper - Statement Closed!");
m_Connection.close();
System.out.println("JDBCWrapper - Connection Closed!");
}
catch (SQLException e)
{
e.printStackTrace();
}
}
return true;
}
private void registerSpParams(ArrayList<StoredProcedureParam> a_ParamList) throws SQLException {
if (a_ParamList.size() > 0)
{
for (int i = 1; i <= a_ParamList.size(); i++)
{
StoredProcedureParam spp = a_ParamList.get(i - 1);
switch (TypesEnum.valueOf(spp.getType()))
{
case Integer:
m_cStatement.setInt(spp.getParamName(), Integer.parseInt(spp.getValue()));
break;
case String:
m_cStatement.setString(spp.getParamName(), spp.getValue());
break;
case NString:
m_cStatement.setNString(spp.getParamName(), spp.getValue());
break;
case Timestamp:
m_cStatement.setTimestamp(spp.getParamName(), Timestamp.valueOf(spp.getValue()));
break;
case output:
switch (TypesEnum.valueOf(spp.getValue()))
{
case Integer:
m_cStatement.registerOutParameter(spp.getParamName(), java.sql.Types.INTEGER);
break;
case Timestamp:
m_cStatement.registerOutParameter(spp.getParamName(), java.sql.Types.TIMESTAMP);
break;
default:
break;
}
break;
case bit:
m_cStatement.setByte(spp.getParamName(), Byte.parseByte(spp.getValue()));
break;
case Bigint:
m_cStatement.setBigDecimal(spp.getParamName(), BigDecimal.valueOf(Long.parseLong(spp.getValue())));
break;
}
}
}
}
For some reason I am getting the exception in subject:
com.microsoft.sqlserver.jdbc.SQLServerException: The index 8 is out of range.
at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDriverError(SQLServerException.java:190)
at com.microsoft.sqlserver.jdbc.SQLServerCallableStatement.registerOutParameter(SQLServerCallableStatement.java:75)
at com.microsoft.sqlserver.jdbc.SQLServerCallableStatement.registerOutParameter(SQLServerCallableStatement.java:1735)
at com.att.ecm.jdbcwrapper.JDBCWrapper.registerSpParams(JDBCWrapper.java:216)
at com.att.ecm.jdbcwrapper.JDBCWrapper.callStoredProcedure(JDBCWrapper.java:138)
at com.client.main.ConferenceStoredProcedures.callAddConferenceSp(ConferenceStoredProcedures.java:74)
at com.main.Main.startFlow(Main.java:51)
at com.main.Main.executeFlow(Main.java:34)
at com.main.Main.main(Main.java:26)
And cannot understand why? As far as I understand I set 7 question marks and set 7 parameters.
So, why does it throws an exception on the 8th index??
Can you advise please?
Best Regards, Tal
The problem was that the stored procedure has more parameters that 7. It has 9.
As I add the 2 parameters and add 2 question marks to the call string - the excption did not happen.
What do you need is a CallableStatement object on which you can prepareCall.
Creates a CallableStatement object for calling database stored procedures. The CallableStatement object provides methods for setting up its IN and OUT parameters, and methods for executing the call to a stored procedure.
To change the above code you need use index in the set methods
likem_cStatement.setInt(i,...
This happened to me when I mapped a parameter and didn't actually use the parameter in the query. Surprised the parameter wasn't simply ignored.
Related
I am trying to update several records from spring jdbc but this is not working what am i doing wrong?
does not respond when I make a request, but the data in the array is arriving, try without array and the same thing happens.
I am sending an array of objects to be able to update but I get to the method cstmt.executeQuery(); it does not execute and it waits and does not go any further.
#PostMapping(path = "/updateEstadoPlanesServicios", produces = MediaType.APPLICATION_JSON)
public String updateEstadoPlanesServicios(#RequestBody String lista) {
ServiciosPlanesUpdateDTO[] fromJson = gson.fromJson(lista, ServiciosPlanesUpdateDTO[].class);
return gson.toJson(consultaPlanesComisionPortal.estadoPlanesServicios(fromJson));
}
#Transactional(rollbackFor = { Exception.class })
public replyDTO estadoPlanesServicios(ServiciosPlanesUpdateDTO[] list) {
System.out.println("data: "+list.toString());
replyDTO re = new replyDTO();
int count = 0;
try {
StringBuilder update = new StringBuilder();
update.append("UPDATE Detalleproductoservicio ");
update.append(" SET loginregistro = ?, estado = 'D', fechasys = sysdate ");
update.append(" WHERE codigo_Servicio = ? and codigo_planproductoservicio = ? and NIT = ?");
try (Connection conexion = obtenerConexion.obtenerConexion(0);
PreparedStatement cstmt = conexion.prepareStatement(update.toString())) {
conexion.setAutoCommit(false);
for(ServiciosPlanesUpdateDTO elements: list) {
//System.out.println(elements.toString());
System.out.println("1 element:"+elements.getLoginRegistro());
System.out.println("2 element:"+elements.getCodigoServicio());
System.out.println("3 element:"+elements.getCodigoPlanProductoServicio());
System.out.println("4 element:"+elements.getNit());
cstmt.setString(1, elements.getLoginRegistro().trim());
cstmt.setInt(2,Integer.parseInt( elements.getCodigoServicio().trim()));
cstmt.setString(3, elements.getCodigoPlanProductoServicio().trim());
cstmt.setString(4, elements.getNit().trim());
count = cstmt.executeUpdate();
//cstmt.execute();
//count++;
//cstmt.addBatch();
//cstmt.executeBatch();
//
}
conexion.commit();
if(count > 0) {
re.setMessage("Status ok,"
+"count: "+count);
re.setExitoso(true);
}else {
re.setExitoso(false);
re.setMessage("failed");
}
}
} catch (Exception e ) {
re.setExitoso(false);
re.setMessage(e.getMessage());
}
return re;
}
this is working I found the problem apparently the database conflicts when I have Oracle SQL Developer open and I make the request by postman this is a little weird but I closed Oracle Developer and it worked.
I have the following function :
protected final ResponseBuilderImpl RESPONSE_BUILDER_IMPL = new ResponseBuilderImpl(); // This is taken from jersey-core-1.11.jar
protected Response buildAcceptedResponse(Object entity) {
return buildResponse(entity, Response.Status.ACCEPTED);
}
protected Response buildResponse(Object entity, Response.Status status) {
return RESPONSE_BUILDER_IMPL.status(status).entity(entity).build();
}
I've tested several cases and noticed that only String is not working, and can't figure out why.
I'm using postman, sending some GET requests
switch (whatToTest){
case 1: //working
log.info("testing case of Interger!! ");
int x = 11;
return buildAcceptedResponse(x);
case 2: // getting as a response Unexpected 'e'
String t = "testing string";
log.info("testing case of String !!");
return buildAcceptedResponse(t);
case 3: //working
log.info("testing case of Boolean !! ");
boolean y = true;
return buildAcceptedResponse(y);
case 4: //not working
log.info("testing case of Object !! ");
Object yy = "test object";
return buildAcceptedResponse(yy);
case 5: //working
log.info("testing case of Object from type int !! ");
Object yyy = 1565746;
return buildAcceptedResponse(yyy);
case 6: //working
log.info("testing case of class with strings and ints!! ");
TestClass e = new TestClass(4,new Integer(7),"test1", false);
return buildAcceptedResponse(e);
/// Adding - when using this case - it works fine
case 7:
log.info("mapping to object");
ObjectMapper om = new ObjectMapper();
Object res = null;
String te = "test test";
try {
res = om.writeValueAsString(te);
} catch (IOException ex) {
ex.printStackTrace();
}
return buildAcceptedResponse(res);
I thought that I might have a problem with primitive types, but int and boolean are returning as they should. Also, a class containing a String inside - is also good.Can someone advise why only Strings are not working ?
Adding -
My function uses :
#GET
#Produces(MediaType.APPLICATION_JSON)
#Path("test/test")
public Response getTest(String someParam);
// Response is sr311-api\0.11\jsr311-api-0.11-sources.jar
I'm new with java and sql query and for the user connexion, I connect to the DB and check if the login exists. Here is what I do :
requete = "SELECT Login,Password,DroitModifAnnuaire,DroitRecepteurDem,DroitResponsableDem,PiloteIso,Administrateur,DroitNews,DroitTenues,DroitEssai,Nom,Prenom FROM Annuaire WHERE Login='"
+ (request.getParameter("login") + "'");
instruction = connexion.createStatement();
jeuResultats = instruction.executeQuery(requete);
try{
jeuResultats.next();
} catch (SQLException e) {
e.printStackTrace();
}
if (jeuResultats.next() == false) {
loadJSP("/index.jsp", request, reponse);
}else {
loadJSP("/views/menu.jsp", request, reponse);
}
The login that I enter is good but it redirect me to index.jspand I have the error : the result set has no current row
I tried to search answer to this error but I didn't found. So why it returns me false ? While when I do System.out.println(jeuResultats.getString(1)); the login is printed.
jeuResultats.next(); moves your result to the next row. You start with 0th row, i.e. when you call .next() it reads the first row, then when you call it again, it tries to read the 2nd row, which does not exist.
Some additional hints, not directly related to the question:
Java Docs are a good place to start Java 8 ResultSet, for e.x., perhaps ResultSet.first() method may be more suited for your use.
Since you are working with resources, take a look at try-with-resources syntax. Official tutorials are a good starting point for that.
Also take a look at prepared statement vs Statement. Again, official guide is a good place to start
Make the below changes in you code. Currently the next() method is shifting result list to fetch the data at 1st index, whereas the data is at the 0th Index:
boolean result = false;
try{
result = jeuResultats.next();
} catch (SQLException e) {
e.printStackTrace();
}
if (!result) {
loadJSP("/index.jsp", request, reponse);
}else {
loadJSP("/views/menu.jsp", request, reponse);
}
Replace your code by below code:
requete = "SELECT Login, Password, DroitModifAnnuaire, DroitRecepteurDem, DroitResponsableDem, PiloteIso, Administrateur, DroitNews, DroitTenues, DroitEssai, Nom, Prenom FROM Annuaire WHERE Login = '"
+ (request.getParameter("login") + "'");
instruction = connexion.createStatement();
jeuResultats = instruction.executeQuery(requete);
try{
if (jeuResultats.next()) {
loadJSP("/index.jsp", request, reponse);
} else {
loadJSP("/views/menu.jsp", request, reponse);
}
} catch (SQLException e) {
e.printStackTrace();
}
I want to cycle through an ArrayList<String> named fileContent, using the Iterator interface, and I want it to be analyzed one string at a time which should result in a specific state by the switch statement, depending on what string it is.
Object token is supposed to be read as 'Table'.
void process() {
Iterator fileIterator = fileContent.iterator();
int state = 0;
Object token = null;
switch (state) {
case 0:
token = fileIterator.next();
if (token.equals("Table")) {
System.out.println(token);
state = 1;
} else {
System.err.println("Corrupt file format at state 0: "+ token);
System.exit(0);
}
break;
}
}
This doesn't switch state to 1, instead it prints out:
'Corrupt file format at state 0: Table'
So it seems as it reads the Object token correctly as 'Table' but not for the statement 'if (token.equals("Table"))'.
I have also tried 'if (token == ("Table"))'
Can somebody help me?
Looks like you want to equate Strings, try this
void process() {
Iterator fileIterator = fileContent.iterator();
int state = 0;
String token = ""; // notice this
switch (state) {
case 0:
token = ((String)fileIterator.next()).trim(); // notice this
if (token.equals("Table")) {
System.out.println(token);
state = 1;
} else {
System.err.println("Corrupt file format at state 0: "+ token);
System.exit(0);
}
break;
}
}
What makes you think "it reads the Object token correctly as 'Table'"? When the if() fails, then token must be something unlike Table. My guess is that the output is misleading. Try this instead:
System.err.println("Corrupt file format at state 0: ["+ token + "]");
The square brackets around the token will help you see unexpected whitespace characters.
Also note that token might not be a string but return Table when toString() is called on it (which will happen if you append it to a string).
I've read the other posts and the docs about how to use the "Where" clause to "create" parenthesis statements.
My requirement is simple:
... WHERE companyID=1 AND (director=true OR officer=true) ;
I'm writing a routine that takes an array of Object, which are then parsed into an Ormlite Where call. a typical call looks like this:
.., "companyID", 1, Q.AND, Q.Bracket, "director", true, Q.OR, "officer", true, Q.Bracket)
The intent is to speed up simple queries. There is no desire to replace Ormlite's querying tools. This is a simple meta-layer on top.
Everything works fine for simple queries, since the parameters are processed sequentially and the where clause is built incrementally.
For parenthesis I am postponing the processing until the bracket is closed.
This is where I am having a problem. The example from the docs I am using shows this:
-- From the OrmLite docs...
Where<Account, String> where = queryBuilder.where();
where.or(
where.and(
where.eq(Account.NAME_FIELD_NAME, "foo"),
where.eq(Account.PASSWORD_FIELD_NAME, "_secret")),
where.and(
where.eq(Account.NAME_FIELD_NAME, "bar"),
where.eq(Account.PASSWORD_FIELD_NAME, "qwerty")));
This produces the following approximate SQL:
SELECT * FROM account
WHERE ((name = 'foo' AND password = '_secret')
OR (name = 'bar' AND password = 'qwerty'))
The key thing I understand from the docs example, is that the same where instance is used in the nested and(...) call. This is precisely what I'm doing but I'm still getting a "Did you forget an AND or an OR" message.
The code implementing the "delayed" processing looks like this:
#SuppressWarnings("unchecked")
private void processWhere(Where<?, ?> where, Q q, List<QValue> list)
{
if (null == list || list.size() < 2)
{
System.err.println("Invalid where passed: " + list);
return;
}
if (q.equals(Q.AND))
where.and(getCondition(where, list.get(0)), getCondition(where, list.get(1)));
else
where.or(getCondition(where, list.get(0)), getCondition(where, list.get(1)));
}
The "QValue" item is just a "holder" for column, condition and value data.
The "getCondition" method is as follows:
#SuppressWarnings("rawtypes")
protected Where getCondition(Where<?, ?> where, QValue qv)
{
if (null != where && null != qv)
return getCondition(where, qv.getType(), qv.getColumn(), qv.getValue(), qv.getValue2());
else
return null;
}
#SuppressWarnings("rawtypes")
protected Where getCondition(Where<?, ?> where, Q cond, String key, Object val, Object val2)
{
if (null == where || null == cond || null == key || null == val)
return null;
SelectArg arg = new SelectArg();
arg.setValue(val);
try
{
switch (cond)
{
case NotNull:
where.isNotNull(key);
break;
case IsNull:
where.isNull(key);
break;
case Equals:
where.eq(key, arg);
break;
case NotEqual:
where.ne(key, arg);
break;
case GreaterThan:
where.gt(key, arg);
break;
case LessThan:
where.lt(key, arg);
break;
case Like:
arg.setValue("%" + val + "%");
where.like(key, arg);
break;
case LikeStart:
arg.setValue("" + val + "%");
where.like(key, arg);
break;
case LikeEnd:
arg.setValue("%" + val);
where.like(key, arg);
break;
case Between:
if (null != val && null != val2)
where.between(key, val, val2);
break;
default:
where.eq(key, arg);
break;
}
}
catch (SQLException e)
{
GlobalConfig.log(e, true);
return null;
}
return where;
}
As far as I can tell, I'm using the Where object correctly, but I am still getting a:
"Did you forget an AND or OR?" message.
I've tried creating "new" Where clauses with QueryBuilder:
Where w1 = qb.where() ;
//process w1 conditions...
return where.query() ;
Which also fails or generates incorrect SQL in the various combinations I've tried. Any suggestions on how to get the and(...) and or(...) methods working properly will be greatly appreciated.
BTW once the library is working properly, I'll put it up as Open Source or donate it to Gray, or both.
Thanks in advance.
Anthony
I faced the same issue and solved it like this:
where.eq("companyID", 1);
where.and(where, where.or(where.eq("director", true), where.eq("officer", true)));
or
where.and(where.eq("companyID", 1), where.or(where.eq("director", true), where.eq("officer", true)));
which in SQL gives us:
((`companyID` = 1 AND `director` = 1 ) OR (`companyID` = 1 AND `officer` = 1 ))
It's not identical to your example clause WHERE companyID=1 AND (director=true OR officer=true) but has the same meaning.