PostgreSQL documentation recommends using a CallableStatement
to call stored procedures.
In the case of a stored procedure that returns a rowset, what are the differences between using CallableStatement
:
String callString = "{ call rankFoos(?, ?) }";
CallableStatement callableStatement = con.prepareCall(callString);
callableStatement.setString(1, fooCategory);
callableStatement.setInt(2, minimumRank);
ResultSet results = statement.executeQuery();
And using a regular PreparedStatement
:
String queryString = "SELECT FooUID, Rank FROM rankFoos(?, ?);";
PreparedStatement preparedStatement = connection.prepareStatement(queryString);
preparedStatement.setString(1, fooCategory);
preparedStatement.setInt(2, minimumRank);
ResultSet results = statement.executeQuery();
As I understand, CallableStatement
offers a language-agnostic way of calling stored procedures. This doesn't matter to me though, since I know I'm using PostgreSQL. As far as I can see, the obvious advantage of using the PreparedStatement
is a more versatile query, treating the stored procedure as a table, on which I can use WHERE
, JOIN
, ORDER BY
, etc.
Are there aspects or differences between the methods that I'm missing? In the case of a stored procedure used as a query, which is recommended?
I'm pretty sure the second approach does not work at all with some RDBMS's, but since you are only going to use PostgreSQL, that shouldn't matter too much. For your simple case, there really isn't much of a downside. There are two issues I can see popping up:
Depending on how the stored procedures are written, they may require you to register out parameters in order to execute the procedure. That's not going to be possible at all with prepared statements. If you control both the creation of the stored procedure and the calling code, you probably don't have to worry about this.
It limits the effectiveness of calling stored procedures in the first place. One of the main advantages of a stored procedure is to encapsulate the querying logic at the database level. This allows you to tune the query or in some cases add functionality without having to make changes to your code. If you're planning on adding where clauses joins to the results of the stored procedure call, why not just put the original query in your java layer?