2012-08-09 60 views
4

如果您只想设置某些参数,那么使用JDBC调用存储过程的最佳方式是什么?如何在JDBC中调用存储过程仅设置某些参数

如果我只是使用SQL,我可以在SQL中通过名称设置参数以调用存储过程。例如。如果我有九个参数的存储过程,我想设置参数1,2和9,留下其余为默认值,我可以运行该SQL:

exec my_stored_procedure 
    @parameter_1  = "ONE", 
    @parameter_2  = "TWO", 
    @parameter_9  = "NINE" 

使用JDBC(具体的jConnect 6.0)看起来在使用CallableStatement时,您必须通过整数索引来设置参数,而不是它们的名称。如果我尝试创建上面的存储过程一个CallableStatement,有9个参数,只设置参数1,2和9,像这样:

myStoredProcedureCall = 
    sybConn.prepareCall("{call my_stored_procedure (?, ?, ?, ?, ?, ? , ?, ?, ?)}"); 
myStoredProcedureCall.setString(1, "ONE"); 
myStoredProcedureCall.setString(2, "TWO"); 
myStoredProcedureCall.setString(9, "NINE"); 
ResultSet paramResults = myStoredProcedureCall.executeQuery(); 

然后我得到此SQLException抛出:

*** SQLException caught *** 
SQLState: JZ0SA 
Message: JZ0SA: Prepared Statement: Input parameter not set, index: 2. 
Vendor: 0 

对于我想要做的一些背景知识,我需要创建一个进程,从IBM MQ流接收关于产品的信息,然后在第三个应用程序中创建一个产品。第三方应用程序使用Sybase来存储其数据,并创建一个产品,我需要调用具有大约130个参数的存储过程。对于需要创建的产品类型,只需要设置其中约15个参数,剩下的参数将保留为默认值。

选项我考虑是:

  • 创建自定义存储过程,只有将我需要的值,然后调用第三方产品的存储过程。
  • 在Java中设置所有参数的默认值。

当然,必须有一个更简单的方法来做到这一点?

回答

6

此功能不通过JDBC支持。你必须创建一个SQL字符串和执行:

String sql = "exec my_stored_procedure\[email protected]_1 = ?,\[email protected]_2 = ?,\[email protected]_9 = ?"; 

PreparedStatement stmt = ... 
stmt.setString(1, "ONE"); 
stmt.setString(2, "TWO"); 
stmt.setString(3, "NINE"); 
stmt.execute(); 

记住:JDBC不试着去了解,你发送到数据库除了一些特殊字符,如{}?的SQL。我曾经写过一个接受JavaScript代码段为“SQL”的JDBC“数据库”:我只是实现了DataSource,ConnectionResultSet,我可以使用JDBC接口查询应用程序的内存模型,但是使用JavaScript作为查询语言。

+1

只是为别人需要的。上面的例子中,String sql中的'\ n'可以替换为一个空格,Sybase不需要单独列出参数,它们只需用逗号分隔。 – alaniane 2017-12-06 23:05:48

+0

@alaniane正确。我从一些代码中复制了一些代码,我也记录了这些语句。换行符只是为了帮助人类解决SQL和SQL问题。 – 2017-12-08 14:36:40

0

您可以尝试硬编码null或空白字符串

"{call my_stored_procedure (?, ?, null, null, null, null , null, null, ?)}"

+1

如果我指定null,该参数不被设置在Sybase存储过程的默认值 – JonnyWizz 2012-08-09 10:06:43

0
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(); 
0

//abobjects.com 下面对我的作品 高清getIDGEN(sTableName):
proc等于db.prepareCall(“{=调用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 

我的存储过程是

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 @[email protected] + 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 
相关问题