Search code examples
javastored-proceduresjdbcparametersinformix

How to pass array of integer to Informix stored procedure


In Java, how do I pass values of type set to a procedure. This seems too basic, but I can't solve it, I spent days searching sample Java code on how to pass set values to Informix procedure.

Tools

IBM Informix Dynamic Server Version 12.10.FC13
JDBC 4.10.14, 4.50.7
Java version "1.8.0_172"

Informix procedure

create procedure sp_demo_set_arg(
    arg1 set(integer not null)
)
...
end procedure

Java code

@Override
public Integer callProcedure(List<Integer> listOfId) {
    String sql = "{ call sp_demo_set_arg(?) }";
    
    @SuppressWarnings("rawtypes")
    java.util.HashSet arg1 = new HashSet();
    Integer intObject;
    int i;
    for (i=1; i <= 3; i++)
    {
        intObject = new Integer(i);
        arg1.add(intObject);
    }       
    
    Connection conn = null;
    try {
        conn = dataSource.getConnection();

        CallableStatement stmt = conn.prepareCall(sql);
        stmt.setObject(1, arg1); 
        stmt.executeUpdate();
        return 0;
    } catch (SQLException e) {
        e.printStackTrace();
    }

    return 1;
}

Stacktrace

...
java.sql.SQLException: Routine (sp_demo_set_arg) can not be resolved.
        at com.informix.jdbc.IfxSqli.addException(IfxSqli.java:3133)
        at com.informix.jdbc.IfxSqli.receiveError(IfxSqli.java:3417)
        at com.informix.jdbc.IfxSqli.dispatchMsg(IfxSqli.java:2324)
        at com.informix.jdbc.IfxSqli.receiveMessage(IfxSqli.java:2249)
        at com.informix.jdbc.IfxSqli.executeCommand(IfxSqli.java:850)
        at com.informix.jdbc.IfxResultSet.executeUpdate(IfxResultSet.java:230)
        at com.informix.jdbc.IfxStatement.executeUpdateImpl(IfxStatement.java:1054)
        at com.informix.jdbc.IfxPreparedStatement.executeUpdate(IfxPreparedStatement.java:396)
        at 
...

Solution

  • Your java code may fail with an -674 "Routine can not be resolved" error because the server may not know the parameter type at execution. Try giving it some 'hints' changing '?' for a '?::SET(integer not null)'

    Something like:

    D:\Infx\work\Java>cat t2.java
    import java.sql.*;
    import java.util.*;
    
    public class t2 {
    
     public static void main( String [] args ) {
    
     Connection conn = null;
     ResultSet dbRes = null;
     Statement is = null;
    
     try {
        Class.forName("com.informix.jdbc.IfxDriver");
    
       conn = DriverManager.getConnection("jdbc:informix-sqli://420ito:9091/stores7:INFORMIXSERVER=ids1410;user=informix;password=passw;SQLIDEBUG=pp;");
    
        is = conn.createStatement();
        is.executeUpdate("drop table t2; create table t2 (c1 SET(integer not null) );");
    
        java.util.HashSet arg1 = new HashSet();
        Integer intObject;
        int i;
        for (i=1; i <= 3; i++)
        {
            intObject = new Integer(i);
            arg1.add(intObject);
        }
    
        try {
            //CallableStatement stmt = conn.prepareCall("{ CALL p2(?)}");
            CallableStatement stmt = conn.prepareCall("{ CALL p2(?::SET(integer not null))}");
            stmt.setObject(1, arg1);
            stmt.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    
        Statement st = conn.createStatement();
        ResultSet rs = st.executeQuery("SELECT * FROM t2");
        while (rs.next()) {
            java.util.HashSet set = (HashSet) rs.getObject(1);
            Iterator it = set.iterator();
            Object obj;
            i = 0;
            while (it.hasNext())
            {
                obj = it.next();
                System.out.println("    element[" + i + "] = " +   obj.toString());
                i++;
            }
        }
        rs.close();
        conn.close();
      }
      catch ( Exception e ) {
        System.err.println(e);
            e.printStackTrace();
       }
     }
    }
    
    
    D:\Infx\work\Java>javac t2.java
    Note: t2.java uses unchecked or unsafe operations.
    Note: Recompile with -Xlint:unchecked for details.
    
    D:\Infx\work\Java>java t2
        element[0] = 1
        element[1] = 2
        element[2] = 3
    
    D:\Infx\work\Java>