2009-09-05 18 views
20

私は、SQLServerへの接続がない場合、SQLDataReaderが動作してはならないと考えていました。DataReaderの仕組みは?

私はこのシナリオを実験しました。 ExecuteReaderを実行してSQLServer Serviceを停止し、DataReaderを反復しようとしました。私が期待したのは例外でしたが、結果を次々に出しました。理想的には、DataReaderはDBサーバーに接続するストリームから一度に1行を読み込み、DBサーバーを切断すると例外がスローされるはずです。

私には分かりませんが、私はここで何が欠けているのですか?

+3

良い実験! – smwikipedia

答えて

25

私は読者が一度に一度に結果のバッチを読むと強く疑う。これは一度に1つの行よりもずっと効率的です(単一の行がほんの数バイトである状況を考えてください...単一のパケットでたくさんの行を取得できたときに行ごとにネットワークパケットを必要としません)。また、データベースが内部リソースを早期に解放する可能性もあります。データリーダーがすべての結果を読み取った場合(わずかな場合)、クエリを効果的に忘れる可能性があります。

多くの結果を返すクエリで同じ種類のものを試してみると、予想される例外が発生すると思われます。

+5

Correct(http://msdn.microsoft.com/en-us/library/ms187602.aspx)、結果はできるだけ早くクライアントに送信され、開かれている接続のインバウンドネットワークバッファが飽和し​​ますサーバー。そのバッファが受け入れる以上のデータを取得しないと、結果のすべての行を取得できます。 –

+0

良い説明! – smwikipedia

+0

ネットワークバッファとは何ですか? plzzは説明します。 – Mou

4

基本的な接続タイプは、一度にどれくらいのデータが供給されるかに影響を与えます。共有メモリコネクタを使用している少量のデータでは、すべてのデータが一緒に送信される可能性があります。

共有メモリは、クライアントとサーバーが同じマシン上にある場合のデフォルトのプロトコルです。

3

バックグラウンドで時間があるので、それを読み込みます。 SQL Serverに接続して接続を閉じるまでに、すべてのデータがバックグラウンドで転送されました。読者を実行すると、SQL Serverが呼び出され、結果の送信が開始されます。クエリの実行が終了すると(正しく解析され、クエリは有効です)、実行が終了する前に戻ります。その時点で、readメソッドを呼び出すことができます。しかし、それでもバックグラウンドでデータを読み込んでバッファリングするので、読み込みを再度呼び出すと、次の行は準備ができてバッファで待機し、データベースに移動する必要はありません。

6

データ・リーダーは、一度にレコードを読み取りますが、基礎となるデータベース・ドライバーからレコードを読み取ります。データベース・ドライバーは、通常は8キロバイトのバッファーを使用して、データベース内のデータをブロック単位で読み取ります。

結果レコードが小さく、あまり多くない場合、それらはすべてバッファに収まり、データベースドライバはデータベースに詳細を要求せずにすべてをデータリーダーに送ることができますデータ。

バッファより大きい結果をフェッチすると、データベースドライバがより多くのデータをデータベースに要求する前に、その最初の部分だけを読み取ることができます。その時点でデータベースにアクセスできない場合は例外が発生します。