PL/SQL supports two different notations for procedure calls, namely
positional notation and named notation. It’s up to the programmer to
decide which method to use; the compiler doesn’t care one whit.
In daily business I was asked whether both notations are supported
through JDBC. The positional notation seems to be familiar, the named notation should be
too after reading this article!
In PL/SQL the following procedure is defined for test purpose:
PROCEDURE mytest
Argument Name
Type In/Out Default?
------------------- ------------- ------ --------
P_MSISDN
VARCHAR2 IN
P_STATUS
NUMBER(38) OUT
P_MESSAGE
VARCHAR2 OUT
P_LANGUAGE
NUMBER(38) IN DEFAULT
Two input parameters are defined, one of them is mandatory, one of them
is optional. Two output parameters are defined to get some info back from the called
procedure.
The positional notation is straight forward as it would be in
PL/SQL:
StringBuffer sbQuery = new StringBuffer(1024);
Connection con = getConnection();
int language = getLanguage();
// Prepare a PL/SQL call
sbQuery.append( "{call mytest( ?, ?, ?" );
if ( language > 0 )
{
sbQuery.append( ", ?" );
}
sbQuery.append( " )}" );
CallableStatement cstmt = con.prepareCall( sbQuery.toString() );
// 1st parameter is the MSISDN (input parameter)
cstmt.setString( 1, "41793333333" );
// 2nd parameter is the returned status (output
parameter)
cstmt.registerOutParameter( 2, OracleTypes.INTEGER );
// 3nd parameter is the returned message (output
parameter)
cstmt.registerOutParameter( 3, OracleTypes.VARCHAR );
// 4th parameter is the language code (optional input
parameter)
if ( language > 0 )
{
cstmt.setInt( 4, language );
}
cstmt.execute();
// Get the returned status
System.out.println(cstmt.getInt( 2 ));
// Get the returned message
System.out.println(cstmt.getString( 3 ));
The order of the parameters is given by the stored procedure. The
optional input parameter p_language is only used, if the language is greater than
zero.
Similar to PL/SQL the named notation can be used in JDBC:
StringBuffer sbQuery = new StringBuffer(1024);
Connection con = getConnection();
int language = getLanguage();
// Prepare a PL/SQL call
sbQuery.append( "{call mytest( p_msisdn => ?" );
sbQuery.append( ", p_message => ?" );
sbQuery.append( ", p_status => ?" );
if ( language > 0 )
{
sbQuery.append( ", p_language => ?" );
}
sbQuery.append( " )}" );
CallableStatement cstmt = con.prepareCall( sbQuery.toString() );
// 1st parameter is the MSISDN (input parameter)
cstmt.setString( 1, "41793333333" );
// 2nd parameter is the returned message (output
parameter)
cstmt.registerOutParameter( 2, OracleTypes.VARCHAR );
// 3rd parameter is the returned status (output
parameter)
cstmt.registerOutParameter( 3, OracleTypes.INTEGER );
// 4th parameter is the language code (optional input
parameter) if ( language > 0 )
{
cstmt.setInt( 4, language );
}
cstmt.execute();
// Get the returned message
System.out.println(cstmt.getString( 2 ));
// Get the returned status
System.out.println(cstmt.getInt( 3 ));
As you can see, this technique prefixes each argument with the name of
the parameter, followed by “=>”, followed by the value. You may have also
noticed that the arguments are in arbitrary positions – we don’t have to
remember or use the order specified in the called procedure.
The advantage of named notation is the self-documenting code through
the obvious assignment of the parameter and its value. Moreover you can define the used
parameters in your preferred order without skipping unused parameters with null.
The disadvantage is slightly more typing effort.
If you have a choice, use named notation whenever it’s not
obvious what the argument corresponds to. Use positional notation with common utility
programs that have only one or two parameters, and their meaning is obvious.
|