11

次のエラーを回避するために、Oracleでlong値を処理するカスタムLongクラスを作成するにはどうすればよいですか?

原因:java.sql.SQLException:ストリームはすでに閉じられています。

ありがとう

4

4 に答える 4

10

Oracle recommends not using Long and Long Raw columns (since Oracle 8i). They are included in Oracle only for legacy reasons. If you really need to use them, the you should first handle these columns before attempting to touch any other columns in the ResultSet:

Docs:

When a query selects one or more LONG or LONG RAW columns, the JDBC driver transfers these columns to the client in streaming mode. After a call to executeQuery or next, the data of the LONG column is waiting to be read.

Do not create tables with LONG columns. Use large object (LOB) columns, CLOB, NCLOB, and BLOB, instead. LONG columns are supported only for backward compatibility. Oracle recommends that you convert existing LONG columns to LOB columns. LOB columns are subject to far fewer restrictions than LONG columns.

As for hibernate - see this question.

于 2012-04-16T13:24:50.793 に答える
6

以下は、「Oracle で long 値を処理するカスタム Long クラスを作成する方法」という元の質問への回答ではありませんが、Oracle の long raw 列をクエリするときに「ストリームは既に閉じられています」というエラーを回避するのに役立つ場合があります。

列タイプを変更する可能性がない従来のデータベースを使用して、このエラーに直面しました。Spring を hibernate3 セッション ファクトリとトランザクション マネージャと共に使用します。この問題は、複数のタスクが同時に DAO にアクセスしているときに発生しました。ojdbc14.jar ドライバーを使用していますが、新しいドライバーを試しましたがうまくいきませんでした。

OJDBC ドライバーの接続プロパティで useFetchSizeWithLongColumn = true を設定すると、問題が解決しました。OracleDriver APIを参照してください

これは薄いだけのプロパティです。他のドライバーと一緒に使用しないでください。「true」に設定すると、「SELECT」でデータを取得するときのパフォーマンスは向上しますが、LONG 列を処理するためのデフォルトの動作は、複数の行をフェッチするように変更されます (プリフェッチ サイズ)。これは、このデータを読み取るために十分なメモリが割り当てられることを意味します。したがって、このプロパティを使用する場合は、取得する LONG 列が大きすぎないことを確認してください。そうしないと、メモリが不足する可能性があります。このプロパティは、Java プロパティとして設定することもできます: java -Doracle.jdbc.useFetchSizeWithLongColumn=true myApplication

于 2012-05-04T13:40:21.197 に答える
0

結果セットから Oracle LONG 値を複数回取得しようとすると、このメッセージが表示されると思います。

次のようなコードがありました:

        rs.getString(i+1) ;
        if (rs.wasNull()) continue ;

        set(queryAttr[i], rs.getString(i+1)) ;

そして、「ストリームは既に閉じられています」というメッセージが表示されるようになりました。エラー。コードを次のように変更すると、エラーが発生しなくなりました。

        String str = rs.getString(i+1) ;
        if (rs.wasNull()) continue ;

        set(queryAttr[i], str) ;
于 2015-03-11T16:03:52.297 に答える