JDBC: возвращение нескольких наборов результатов через один вызов базы данных - не работает для Oracle - PullRequest
8 голосов
/ 14 декабря 2011

В этом посте было показано выполнение нескольких запросов за один вызов 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();
    }
}

Что я делаю не так?

Ответы [ 2 ]

7 голосов
/ 14 декабря 2011

Вы не делаете ничего плохого (кроме предположения, что все СУБД работают одинаково)

Oracle (и его драйвер JDBC) просто не поддерживают это.

Вам нужно запустить каждый SELECT отдельно.

Кстати: это одна из причин того, что некоторые атаки с использованием SQL-инъекций не работают с Orace, особенно знаменитый мультфильм " маленькие заколки ".

1 голос
/ 06 декабря 2015

Можно получить несколько наборов результатов из Oracle в JDBC за один вызов.Есть несколько способов сделать это;Хороший пост в Oracle-Base показывает, как .

Механизм, который я использую, состоит в том, чтобы создать анонимный блок в вызываемом выражении, а затем связать 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();
}

Я надеюсь, что это поможет вам!

...