5

JDBCを介して複数の結果セットを返すSybaseストアドプロシージャを呼び出しています。「結果」という名前の列を持つ特定の結果セットを取得する必要がありますこれは私のコードです:

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、ターゲットの結果セットに到達するまで、多くのnull結果セットが返されます。cs.getMoreResultsnullの結果セットに対してfalseを返すため、ループ条件として使用できません。

ループが無限ループになるのを防ぐために、必要な結果セットが返されない状態でループを終了するために、固定数を設定しました。うまくいきましたが、これは正しくないと思います。

Sybaseの割り当てから返されたnullの結果セットだと思いますselect @variable = value

誰かが以前にこれに直面したことがありますか?

4

1 に答える 1

7

の戻り値を誤解していますgetMoreResults()。の戻り値も無視していますexecute()。このメソッドはboolean、最初の結果の型を示す を返します。

  • true: 結果はResultSet
  • false: 結果は更新回数です

結果が の場合はtrueを使用getResultSet()して を取得しResultSet、それ以外の場合getUpdateCount()は更新回数を取得します。更新回数が-1である場合、これ以上結果がないことを意味します。更新カウントは-1、現在の結果がResultSet. getResultSet()結果がそれ以上ない場合、または結果が更新カウントである場合は、 null を返す必要があることも知っておくとよいでしょう (この最後の条件が、非常に多くのnull値を取得する理由です)。

より多くの結果を取得したい場合は、 (またはパラメーターgetMoreResults()を受け入れる兄弟) を呼び出します。intの戻り値は の戻り値とboolean同じ意味を持つexecute()ため、これfalse 以上結果がないわけではありません

getMoreResults()がfalse を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;ます。

注: この回答の一部は、Java アプリケーションで「sp_msforeachdb」を実行するという私の回答に基づいています。

于 2013-02-12T09:35:48.337 に答える