JDBC executeQuery() возвращает и ResultSet, и выходные параметры

Я звоню одному sp с несколькими выходными параметрами, и в соответствии с моим требованием мне нужно использовать ResultSet при некоторых условиях и без параметров при других условиях. Но используя executeQuery(), я получаю, JZ0R0: ResultSet уже был закрыт ошибка (я использую Sybase 15)

Вот пример:

Connection conn = ~~;        
CallableStatement cstmt = conn.prepareCall("{call my_sp(?)");
cstmt.registerOutParameter(1,java.sql.Types.INTEGER);
ResultSet rs = cstmt.executeQuery();

Если я попытаюсь сделать, ниже код сейчас,

int res = cstmt.getInt(1);

Затем попробуйте выполнить итерацию объекта ResultSet, как показано ниже, затем я получаю выше ResultSet ошибка закрытия.

ResultSetMetaData rsmd = rs.getMetaData();

Есть ли способ, которым я могу получить значение выходного параметра и затем выполнить итерацию на объект ResultSet или наоборот?

2 ответа

В соответствии со спецификацией JDBC вы должны получить результирующий набор до вывода параметров

Вот оригинальная спецификация

7.1.7 Извлечение параметров OUT после результатов

Из-за ограничений, налагаемых некоторыми СУБД, рекомендуется, чтобы для максимальной переносимости все результаты в объекте ResultSet, сгенерированном при выполнении объекта CallableStatement, были получены до того, как будут получены параметры OUT. Когда все значения получены из результирующего набора, метод ResultSet.next вернет false.

Если объект CallableStatement возвращает несколько объектов ResultSet (что возможно только в том случае, если он выполняется с вызовом метода execute), все результаты должны быть получены до получения параметров OUT. В этом случае, чтобы быть уверенным в доступе ко всем результатам, необходимо вызывать методы Statement getResultSet, getUpdateCount и getMoreResults до тех пор, пока больше не будет результатов. Когда все результаты исчерпаны, метод getMoreResults возвращает значение false, а метод getUpdateCount возвращает значение -1.

Я не знаком с SyBase,
но может быть, вы можете вывести сценарий, как этот StoredProcedure в MSSQL:

DECLARE @RC int
DECLARE @pUserID nvarchar(50)
DECLARE @pDepartmentID int

-- TODO: Set parameter values here.

EXECUTE @RC = [AccessMgrDB].[dbo].[SP_GenerateAbsentPresentReport] 
   @pUserID
  ,@pDepartmentID

GO  

и идти с кодом Java:

set.con.setAutoCommit(false); 
        Statement st2 = set.con.createStatement(); 

        String queryAbsent = "DECLARE @RC int\n" +
            "DECLARE @pUserID nvarchar(50)\n" +
            "DECLARE @pDepartmentID int\n" +
            "EXECUTE ["+dbSrcNames+"].[dbo].[SP_GenerateAbsentPresentReport] \n" +
            ""+USER +
            ","+DPTID+"";

        ResultSet rs2 = st2.getGeneratedKeys();

        while (rs2.next()){
              String userID = rs2.getString("UserID");
              Date logDate = rs2.getDate ("logDate");
              String logDay = rs2.getString("logDay");
              String status = rs2.getString ("status");
              int pivot = rs2.getInt ("pivotvalue");
              int pivot2 = rs2.getInt ("pivotvalue2");
              if(status.equals("Absent"))

                  absent.add(logDate.toString());

              if(status.equals("Present"))

                  present.add(logDate.toString());

        st2.getMoreResults(java.sql.Statement.CLOSE_CURRENT_RESULT);

        set.con.commit();

Когда-то у меня была такая же проблема в вызове StoredProcedure, и это было всего несколько дней назад;)

Другие вопросы по тегам