0

I need some suggestion on how to get the data through PostgreSQL JDBC driver from stored procedures using reference cursors.

Since PostgreSQL 11, it supports stored procedures with create procedure command instead of create function.

I have a scenario in which I want to fetch data from a stored procedure using a reference cursor.

My stored procedure SQL looks like as shown below

CREATE OR REPLACE PROCEDURE public.pr_sampleuser(
    p_firstuser character varying,
    INOUT p_qusers refcursor)
LANGUAGE 'plpgsql'
AS $BODY$

BEGIN
   OPEN p_qusers FOR
   SELECT first_name,last_name,address
   FROM public.test_user
   WHERE UPPER(first_name) = UPPER(p_firstuser);
END; 
$BODY$;

When we want to fetch the data using the JDBC driver, the first thing we need to add to the connection string is escapeSyntaxCallMode=call.

Following is the code-snippet that I am using to fetch the data,

try {
    Properties props = new Properties();
    props.setProperty("escapeSyntaxCallMode", "call");
    Connection conn = DriverManager.getConnection(url,props);
    String storedProc = "{call public.pr_sampleuser(?,?)}";
    CallableStatement cs = conn.prepareCall(storedProc);
    cs.setString(1,"Umesh");
    cs.setObject(2,null);
    cs.registerOutParameter(2,Types.REF_CURSOR);
    conn.setAutoCommit(false);

    // run StoredProcedure
    cs.execute();

    // get refcursor and convert it to ResultSet
    ResultSet resultSet = (ResultSet) cs.getObject(2);
    while (resultSet.next()) {
        String firstName = resultSet.getString("first_name");
        String lastname = resultSet.getString("last_name");
        String address = resultSet.getString("address");

        System.out.println(firstName);
        System.out.println(lastname);
        System.out.println(address);
    }
} catch (SQLException e) {
    System.err.format("SQL State: %s\n%s", e.getSQLState(), e.getMessage());
    e.printStackTrace();
} catch (Exception e) {
    e.printStackTrace();
}

In this I am passing the second parameter as null using

cs.setObject(2,null);

I wanted to check if this is the correct way to fetch or if there is any better way to get the data.

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
Ashu
  • 163
  • 4
  • 13
  • This would be so much easier if you use a set-returning function instead of a procedure. Then it's as simple as running `select * from pr_sampleuser()` –  Feb 17 '23 at 07:44
  • does this post (https://stackoverflow.com/questions/15671636/testing-postgresql-functions-that-consume-and-return-refcursor/15675036#15675036) answer your question... – jian Feb 17 '23 at 08:02
  • @a_horse_with_no_name: sry but i am not looking for workrounds, consider that aspect that procedure is already created for you, i am asking for how to access it correctly using JDBC. Jian: The post you have mentioned is about stored proc creation and calling it, i am looking forward to access the data through JDBC driver and it this is the best way to read the data. – Ashu Feb 17 '23 at 08:50
  • Well, a procedure is the wrong thing to use, if a result set should be returned. Using a function is not a "workaround", it's the correct solution to the problem here. –  Feb 17 '23 at 08:51
  • @a_horse_with_no_name: See thats another aspect, but the procedures have already been created and i believe its not wrong as per https://www.enterprisedb.com/docs/jdbc_connector/latest/08_advanced_jdbc_connector_functionality/04_using_ref_cursors_with_java/ – Ashu Feb 17 '23 at 08:56
  • Does it work? If so, this seems to be the correct solution, and then I am unsure why you're asking this question... – Mark Rotteveel Feb 17 '23 at 09:36
  • @MarkRotteveel: yes this solution works, my concern was around why we need to use cs.setObject(2,null); Is it that for referenceCursors we need to set the value of 2nd parameter to null or if there is any better way of doing this? – Ashu Feb 17 '23 at 09:45
  • You need to set it because you declared the argument of the stored procedure as INOUT. Consider declaring it only OUT, then you shouldn't need to set it. – Mark Rotteveel Feb 17 '23 at 12:01
  • @MarkRotteveel: That is true, just that PostGres13 doesn't support Out Parameters, i think they are available only with PostGres version 14 , https://www.dbi-services.com/blog/postgresql-14-will-support-out-parameters-for-procedures/ – Ashu Feb 19 '23 at 14:02

0 Answers0