This post显示在单个JDBC调用(针对SQL Server数据库)中执行多个查询,方法是用分号分隔它们。当我尝试对Oracle 10G执行相同操作时,会出现错误“无效字符”:
class db
{
public static void main(String aa[])throws Exception
{
Class.forName("oracle.jdbc.driver.OracleDriver");
Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@//192.168.10.29:1521/ttt","username","password");
PreparedStatement stat = conn.prepareStatement("select voila from app where rownum<4; select code from process where rownum<4");
stat.execute();
while (stat.getMoreResults()){
ResultSet rs = stat.getResultSet();
while (rs.next()){
System.out.println(rs.getString(1));
}
}
conn.close();
}
}
我做错了什么?
答案 0 :(得分:7)
你没有做错任何事(除了假设所有DBMS都一样)
Oracle(及其JDBC驱动程序)根本不支持此功能。
您需要单独运行每个SELECT。
Btw:这是一些SQL注入攻击无法与Orace一起工作的原因之一 - 尤其是着名的“little bobby tables”漫画。答案 1 :(得分:1)
可以在一次调用中将多个结果集从Oracle返回到JDBC。有几种方法可以做到;一个good post at Oracle-Base shows how。
我使用的机制是在可调用语句中创建一个匿名块,然后将每个结果集的SYS_REFCURSOR
绑定为输出参数。
这里有一些代码可以做到这一点。它对于错误处理很懒惰,但它可以解决这个问题:
public void getMultiple() throws Exception {
// get connection
Connection conn = DriverManager.getConnection(TestConfig.JDBC_URL, TestConfig.DB_USERNAME, TestConfig.DB_PASSWORD);
// here's the statement; it uses an anonymous block. In that block,
// we've declared two SYS_REFCURSOR objects which are opened over our
// SELECT statements. Once the statements are opened, we bind the
// SYS_REFCURSOR objects so they can be retrieved from JDBC
String s =
"DECLARE" +
" l_rs1 SYS_REFCURSOR; " +
" l_rs2 SYS_REFCURSOR; " +
"BEGIN "+
" OPEN l_rs1 FOR " +
" SELECT 'Moose' FROM DUAL;" +
" OPEN l_rs2 FOR " +
" SELECT 'Squirrel' FROM DUAL; " +
" ? := l_rs1;" +
" ? := l_rs2;" +
"END;";
// prepare the callable statement, registering
// the output parameter we want
CallableStatement cs = conn.prepareCall(s);
cs.registerOutParameter(1, OracleTypes.CURSOR);
cs.registerOutParameter(2, OracleTypes.CURSOR);
// execute the callable statement
cs.execute();
// retrieve the result sets by getting the bound output objects and
// casting them to Java ResultSet objects
ResultSet rs1 = (ResultSet) cs.getObject(1);
ResultSet rs2 = (ResultSet) cs.getObject(2);
// advance the first result set and print the string it yields
rs1.next();
System.out.printf("Result set 1 has '%s'\n", rs1.getString(1));
// advance the second result set and print the string it yields
rs2.next();
System.out.printf("Result set 2 has '%s'\n", rs2.getString(1));
// close everything up
rs2.close();
rs1.close();
cs.close();
conn.close();
}
我希望能帮到你!