2013-02-12 4 views
4

Я вызываю хранимую процедуру Sybase, которая возвращает несколько результирующих наборов через JDBC. мне нужно получить определенный набор результатов, который имеет столбец с именем «Результат» Это мой код:Нулевые результаты при вызове хранимой процедуры Sybase через JDBC

CallableStatement cs = conn.prepareCall(sqlCall); 
cs.registerOutParameter(1, Types.VARCHAR); 
cs.execute(); 
ResultSet rs=null; 
int count = 1; 
boolean flag = true; 
while (count < 20000 && flag == true) { 
    cs.getMoreResults(); 
    rs = cs.getResultSet(); 
    if (rs != null) { 
     ResultSetMetaData resultSetMetaData = rs.getMetaData(); 
     int columnsCount = resultSetMetaData.getColumnCount(); 
     if (resultSetMetaData.getColumnName(1).equals("Result")) { 
      // action code resultset found 
      flag = false; 
      // loop on the resultset and add the elements returned to an array list 
      while (rs.next()) { 
       int x = 1; 
       while (x <= columnsCount) { 
        result.add(rs.getString(x)); 
        x++; 
       } 
      } 
      result.add(0, cs.getString(1)); 
     } 
    } 
    count++; 
} 

Что здесь происходит, что cs.getMoreResults возвращает много пустых ResultSets, пока она не достигнет цели один. Я не могу использовать cs.getMoreResults как условие цикла, потому что он возвращает false для нулевых наборов результатов.

Я положил фиксированное число, чтобы закончить цикл в условии, что желаемый результирующий набор не был возвращен, чтобы предотвратить его переход в бесконечный цикл. Он работал нормально, но я не думаю, что это правильно.

Я думаю, что нулевые результирующих возвращаемые задания в Sybase select @variable = value

Кто-нибудь сталкивался раньше?

ответ

7

Вы неверно истолковываете возвращаемое значение getMoreResults(). Вы также игнорирование возвращаемого значения execute(), этот метод возвращает boolean, указывающий тип первого результата:

  • true: результат является ResultSet
  • false: результатом является счетчик обновления

Если результат true, то вы используете getResultSet() для извлечения ResultSet, в противном случае getUpdateCount(), чтобы получить счетчик обновлений. Если количество обновлений -1 это значит, что результатов не найдено. Обратите внимание, что количество обновлений также будет -1, если текущим результатом является ResultSet. Также полезно знать, что getResultSet() должен возвращать null, если результатов больше нет, или если результат является числом обновлений (это последнее условие - почему вы получаете так много значений null).

Теперь, если вы хотите получить больше результатов, вы вызываете getMoreResults() (или его брат принимает параметр int). Возвращаемое значение boolean имеет то же значение, что и execute(), поэтому falseне означает, что результатов больше нет!

Там не только больше никаких результатов, если getMoreResults() возвращает ложные и getUpdateCount() возвращает -1 (а также документированные в Javadoc)

По сути, это означает, что если вы хотите, чтобы правильно обработать все результаты, которые вы должны сделать что-то, как показано ниже :

boolean result = stmt.execute(...); 
while(true) { 
    if (result) { 
     ResultSet rs = stmt.getResultSet(); 
     // Do something with resultset ... 
    } else { 
     int updateCount = stmt.getUpdateCount(); 
     if (updateCount == -1) { 
      // no more results 
      break; 
     } 
     // Do something with update count ... 
    } 
    result = stmt.getMoreResults(); 
} 

Я предполагаю, что вы получаете много счетчиков обновлений, прежде чем получить фактические ResultSet.

Я не очень хорошо знаком с Sybase, но у его двоюродного брата SQL Server есть функция «раздражающая», чтобы возвращать подсчет обновлений из хранимых процедур, если вы явно не положили SET NOCOUNT ON; в начале хранимой процедуры.

Примечание: Часть этого ответа основана на моем ответе Execute “sp_msforeachdb” in a Java application

+0

Я побежал в этот же вопрос с Sql Server и вы ответ помог мне решить. Я не мог понять, почему 'stmt.execute()' с некоторыми данными возвратит 'false', хотя я мог бы четко видеть данные в наборах результатов, возвращаемых при его запуске вручную. Я все еще не уверен, что понимаю «updateCount()», так как я не верю, что хранимая процедура фактически обновляет любые данные. – Catfish

+0

@Catfish Вы можете попробовать добавить «SET NOCOUNT ON» в ваш sp. –

+0

У меня нет доступа для изменения хранимой процедуры. Вы отвечаете, кажется, работает в моем случае. Благодарю. – Catfish

Смежные вопросы