Java 返回CallableStation.executeQuery()和函数调用的是什么?
假设有一个Oracle PL/SQL过程,它接收IN参数并返回OUT游标参数。我有一个执行此过程的jdbc代码:Java 返回CallableStation.executeQuery()和函数调用的是什么?,java,sql,oracle,jdbc,plsql,Java,Sql,Oracle,Jdbc,Plsql,假设有一个Oracle PL/SQL过程,它接收IN参数并返回OUT游标参数。我有一个执行此过程的jdbc代码: DataSource dataSource; //datasource was set CallableStatement statement = null; ResultSet result = null; ResultSet secondaryResult = null; Connection connection = null;
DataSource dataSource;
//datasource was set
CallableStatement statement = null;
ResultSet result = null;
ResultSet secondaryResult = null;
Connection connection = null;
try {
connection = dataSource.getConnection();
statement = connection.prepareCall("{? = call pl_sql_func(?)}");
statement.registerOutParameter(1, OracleTypes.CURSOR);
statement.setString(2,"param");
// !
secondaryResult = statement.executeQuery();
secondaryResult.close();
result = (ResultSet) statement.getObject(1);
while(result.next()){
//get some data
}
} catch (Exception ex){
}
finally{
//closing statement, result, secondaryResult and connection
}
我尝试执行这段代码,看到secondaryResult没有数据,但result有。这很正常,但有人能解释一下吗
1)语句.executeQuery()真正产生了什么?
2)当语句生成过程调用时,返回的ResultSet是否包含数据?还是它总是空的?
另外,可能的优化不是这个问题的目标。我希望代码按原样解释。您的语句在输出参数中获得结果。根据Oracle教程,这是如何将结果集获取为CallableStatement.executeQuery返回值
statement = connection.prepareCall("{call pl_sql_func(?)}");
这个例子是针对MySQL的,但是想法很清楚
statement.registerOutParameter(1, OracleTypes.CURSOR);
我可以安全地假设您的数据库SQL过程不应该返回游标,而是调用
secondaryResult = statement.executeQuery();
如果要导入Oracle的ODBC驱动程序(而不是通用Java驱动程序),请使用:
从OracleCallableStatement调用executeQuery的行为。CallableStatement不是一个类,而是由JDBC开发人员(在本例中为Oracle)创建的
(注:您应该安装OracleCallableStatement。)
当你写作时
result = (ResultSet) statement.getObject(1);
看起来你是在假装,那样的话,使用它更有意义
ResultSet result = cstmt.getCursor(1);
statement = connection.prepareCall("{? = call pl_sql_func(?)}");
不生成过程,但为。因此,调用过程应该始终输出您应该从中获取数据的结果集。如果你使用
secondaryResult.close();
您将使用假装使用的数据关闭结果集(同样,如果您使用的是Oracle JDBC)
//PostgreSQL
ResultSet rs=null;
CallableStatement stmt=null;
String sqlQuery = "{ call pl_sql_func(?)}";//no out param needed here
stmt=conn.prepareCall(sqlQuery);
stmt.setString(1, "param");//just 1 input param
ResultSet rss =null;
rss = stmt.executeQuery();
if(rss!=null&&rss.next()){
rs = (ResultSet)rss.getObject(1);
rss.close();
}
while(rs.next()){
//get data here
}
请注意,在PostgreSQL中,您甚至不必使用RegisterOutParameter指定OUT参数(尽管这样做更好)。正如您所见,不同的数据库可以以不同的方式处理此问题。请参阅问题后记:“。可能的优化不是此问题的目标。我希望代码按原样解释。”这是错误的。如果存储过程/函数返回游标,则该游标应映射到结果集。@dsp\U用户希望此更正有意义。使用oracle.jdbc.*库应该自动将游标映射到结果集,请参见我答案的最后一行。您可以看到一个示例。
//PostgreSQL
ResultSet rs=null;
CallableStatement stmt=null;
String sqlQuery = "{ call pl_sql_func(?)}";//no out param needed here
stmt=conn.prepareCall(sqlQuery);
stmt.setString(1, "param");//just 1 input param
ResultSet rss =null;
rss = stmt.executeQuery();
if(rss!=null&&rss.next()){
rs = (ResultSet)rss.getObject(1);
rss.close();
}
while(rs.next()){
//get data here
}