What is the best way to make a call to a stored procedure using JDBC if you only want to set some of the parameters?
If I was just using SQL, I could set the paramerers by name in the SQL to call the sproc. E.g. if I have a stored procedure with nine parameters and I wanted to set parameters 1,2 and 9, leaving the rest to their default values, I can run this SQL:
exec my_stored_procedure
@parameter_1 = "ONE",
@parameter_2 = "TWO",
@parameter_9 = "NINE"
Using JDBC (Specifically jConnect 6.0), it seems that when using a CallableStatement, you have to set the parameters by their integer index, not their name. If I try the to create a CallableStatement for the above stored procedure, with 9 parameters, and only set parameters 1,2 and 9, like this:
myStoredProcedureCall =
sybConn.prepareCall("{call my_stored_procedure (?, ?, ?, ?, ?, ? , ?, ?, ?)}");
myStoredProcedureCall.setString(1, "ONE");
myStoredProcedureCall.setString(2, "TWO");
myStoredProcedureCall.setString(9, "NINE");
ResultSet paramResults = myStoredProcedureCall.executeQuery();
Then I get this SQLException thrown:
*** SQLException caught ***
SQLState: JZ0SA
Message: JZ0SA: Prepared Statement: Input parameter not set, index: 2.
Vendor: 0
For some background on what I am trying to do, I need to create a process that receives information about products from a IBM MQ stream, and then creates a product in a 3rd application. The 3rd party application uses Sybase to store it's data, and to create a product I need to call a stored procedure that has about 130 parameters. For the type of product I need to create, only about 15 of these parameters need to be set, the rest will be left to the default values.
Options I have considered are:
- Creating a custom stored procedure that sets only the values that I need, then calls the 3rd party product sproc.
- Setting default values for all parameters in the Java.
Surely there must be an easier way to do this?
This feature isn't supported by JDBC. You will have to create an SQL string and execute that:
String sql = "exec my_stored_procedure\n@parameter_1 = ?,\n@parameter_2 = ?,\n@parameter_9 = ?";
PreparedStatement stmt = ...
stmt.setString( 1, "ONE" );
stmt.setString( 2, "TWO" );
stmt.setString( 3, "NINE" );
stmt.execute();
Remember: JDBC doesn't try to understand the SQL that you're sending to the database except for some special characters like {}
and ?
. I once wrote a JDBC "database" which would accept JavaScript snippets as "SQL": I simply implemented DataSource
, Connection
and ResultSet
and I could query my application's memory model using the JDBC interface but with JavaScript as query language.
You can try hard coding null or blank in the String
"{call my_stored_procedure (?, ?, null, null, null, null , null, null, ?)}"
myStoredProcedureCall.setString(9, "NINE");
in above code index no 9 but it will be 3 because your parameter sequence start from 1 ;
Alhrough you can another sql exception.
I think you should use
myStoredProcedureCall =
sybConn.prepareCall("{call my_stored_procedure (?, ?, null, null, null, null , null, null, ?)}");
myStoredProcedureCall.setString(1, "ONE");
myStoredProcedureCall.setString(2, "TWO");
myStoredProcedureCall.setString(3, "NINE");
ResultSet paramResults = myStoredProcedureCall.executeQuery();
//abobjects.com
Below works for me
def getIDGEN( sTableName ):
proc = db.prepareCall("{ ? = call DB.dbo.usp_IDGEN_string_v6(?, ?) }");
proc.registerOutParameter(3, types.INTEGER)
proc.setString(2, sTableName)
proc.setInt(3, 0)
proc.execute()
li_RI_ID = proc.getInt(3)
print str(li_RI_ID) + " obtained from usp_IDGEN_string_v6"
return li_RI_ID
my sproc is
create proc usp_IDGEN_string_v6 (@tablename varchar(32) , @ID numeric )
as
declare @seq numeric
declare @nextID numeric
select @nextID=IDGEN_ID from DB_IDGEN where IDGEN_TableName = @tablename
select @seq=@nextID + 1 from DB_IDGEN where IDGEN_Table
Name = @tablename
update DB_IDGEN set IDGEN_ID = @seq where IDGEN_TableName = @tablename
select @ID = @seq
return @ID