2016-07-10 17 views
0

jdbcを使用してOracle DBサーバーを使用してチームを構成しています。私の変更の1つでは、私は2つの異なるResultSetsを返すストアドプロシージャを呼び出しています。最初は、私の実装ではデフォルトのスクロール能力が仮定されていました。 それが失敗した後、私はインターネットでそれを調べました。Oracle DBからスクロール可能な結果セットを取得する

私がそれについて読むことができるすべては基本的に同じことを言った:適切なTYPE_SCROLL_INSENSITIVECONCUR_READ_ONLYとのprepareStatementまたはprepareCallメソッドを使用してください。これらのどれも働かなかった。

ストアドプロシージャ私は再び2つの異なる結果セットを返し、それらは(ResultSet) rs.getObject("name")で抽出されます。一般的な例では、ResultSetは.executeQueryから瞬時に戻ります。 私の質問は、prepareCallメソッドのScrollablility/Updatabilityタイプは、このようなResultSetに影響しますか?もしそうなら、どうすればそれらを入手できますか

私は、JDBCドライバがScrollableResultSetのリクエストを低下させる可能性があることを知っています。 結果セットが劣化しているかどうかをどのように確認できますか?

注意:デフォルトではResultSetはスクロールできないのはなぜですか?ベストプラクティスとは何ですか?柔軟性の「コスト」は何ですか?

答えて

3

Oracleでは、カーソルはフォワードのみの構造です。すべてのデータベースは、次の行(技術的には次のn行)をフェッチする方法を知っています。 ResultSetをスクロール可能にするには、JDBCドライバーを使用します。

JDBCドライバには、ResultSetをスクロール可能にするための2つの基本的な方法があります。 1つ目は、逆方向に移動したい場合に備えて、データをフェッチするときに、結果セット全体をメモリに保存することです。機能的には機能しますが、クエリがかなりの量のデータを返す可能性がある場合は、パフォーマンスとスケーラビリティに関して致命的な結果を招く可能性があります。最初に、いくつかの長いコードが含まれている何千もの行がクエリで返されたため、アプリケーションサーバー上でGBのRAMを噛み砕くようになったのは、そのJDBCドライバがリソース豚として正しくピルシングされるからです。

より一般的なアプローチは、ドライバがクエリにキーを追加し、そのキーを使用してドライバがキャッシュするデータを管理することです。したがって、たとえば、ドライバは最後の1000行をメモリ全体に保持し、前の行のキーだけをキャッシュして、後でそのデータを再度フェッチすることができます。コード化するのがより複雑ですが、ResultSetに固有のキーが必要です。通常、これはクエリにROWIDを追加することによって行われます。そのため、たとえば、Oracle JDBCドライバは、スクロール可能または更新可能なResultSet cannot use a SELECT *を指定しますが、SELECT alias.*を使用できます。後者の場合、ドライバは潜在的に盲目的にROWID列をクエリに追加できます。

しかし、ストアドプロシージャから来たResultSetはドライバにとって完全に不透明です。ResultSetを開くために使用されたクエリを取得する方法がないため、追加のキー列を追加する方法も、戻り、再度データをフェッチします。ドライバがResultSetをスクロール可能にしたければ、メモリ内のResultSet全体をキャッシュする必要があります。技術的には、これは完全に可能ですが、パフォーマンス上の問題を引き起こす傾向があるため、ドライバはほとんどありません。 ResultSetをダウングレードする方がずっと安全です。ほとんどの場合、アプリケーションは、少量のデータを返すだけであるか、または戻って行をフェッチすることができることがわかっているため、ResultSet全体をキャッシュするのが妥当かどうかを判断するのに適しています彼らの自然な鍵によって。

ResultSetでgetType()およびgetConcurrency()メソッドを使用して、ResultSetがドライバによってダウングレードされているかどうかを判断できます。

+0

あなたのリンクに添付されているOracle APIが本当にうれしいです。これまでのところ私はそのような広範な答えのために間違った場所を探していました。 しかし、劣化に関しては、 'getType()'と 'getConcurrency()'だけでResultSetのプロパティを問い合わせることができます。私は、そのような劣化が行われたことを示すフラグをチェックすることにもっと興味があります。なぜなら、私は 'スクロール可能なResultset'に対して' JDBC'を正しく指示しているとは確信していないからです。しかし、私はここからオラクルのドキュメントを使って問い合わせることができると思います。 Vielen Dank – Aviv