28

SqlDataReaderがあり、SqlDataReader.GetBytes()メソッドを使用してそこからvarbinary(max)列を読み取る必要があります。このメソッドはバイト配列にデータを入力するため、読み取るデータの長さを知る必要があります。

これは私が混乱するところです..明らかに、この行/列でデータベースから返されたすべてのデータを読み取りたいので、どの「長さ」パラメーターを渡す必要がありますか?

私が見る限り、SqlDataReaderは、使用可能なデータの長さを検出するためのメソッドを提供していません。したがって、このメソッドは私にはかなり厄介なようです。

ここでint.MaxValueを渡して問題を忘れたくなりますが、これに関する何かが私にはぴったりではありません。

代わりに電話できることを知っています

byte[] value = (byte[])dataReader["columnName"];

..そしてこれは内部で長さの問題を完全に処理しているようです。ただし、私はSqlDataReader.GetXXXX()メソッドを中心に構築された一連の複雑なコード生成テンプレートを使用しています。したがって、私はGetBytesの使用に縛られており、その適切な使用法を理解する必要があります。

4

2 に答える 2

45

を扱う場合varbinary(max)、2つのシナリオがあります。

  • データの長さは中程度です
  • データの長さが大きい

GetBytes()は、データをバッファリングするのではなく、ストリーミングしていることを確認するために使用している2番目のシナリオを対象としています。特に、この使用法では、通常、(たとえば)ストリームまたはループで書き込みを行います。例えば:CommandBehaviour.SequentialAccess

// moderately sized buffer; 8040 is a SQL Server page, note
byte[] buffer = new byte[8040]; 
long offset = 0;
int read;
while((read = reader.GetBytes(col, offset, buffer, 0, buffer.Length)) > 0) {
    offset += read;
    destination.Write(buffer, 0, read); // push downstream
}

でも!適度なサイズのデータ​​を使用している場合は、元のコードは次のとおりです。

byte[] data = (byte[])reader[col];

結構です!!。このアプローチには何の問題もありません。実際、Get*APIが壊れている場合がいくつかありGetChar()ます。これは注目に値する例です(ヒント:機能しません)。

を使用する既存のコードがあるかどうかは関係ありませんGet*。この場合、キャストアプローチが完全に適切です。

于 2012-06-21T09:48:36.653 に答える
3

あなたはおそらくこれを行うことができます。MSDN で見つかりました。おそらくそれはあなたの目的を果たすことができます

    // Reset the starting byte for the new BLOB.
  startIndex = 0;

  // Read the bytes into outbyte[] and retain the number of bytes returned.
  retval = myReader.GetBytes(1, startIndex, outbyte, 0, bufferSize);

 // Continue reading and writing while there are bytes beyond the size of the buffer.
  while (retval == bufferSize)
  {
    bw.Write(outbyte);
    bw.Flush();

    // Reposition the start index to the end of the last buffer and fill the buffer.
    startIndex += bufferSize;
    retval = myReader.GetBytes(1, startIndex, outbyte, 0, bufferSize);
  }

  // Write the remaining buffer.
  bw.Write(outbyte, 0, (int)retval - 1);
  bw.Flush();

http://msdn.microsoft.com/en-us/library/87z0hy49%28v=vs.71%29.aspx#Y132

またはこれ

int ndx = rdr.GetOrdinal("<ColumnName>");
            if(!rdr.IsDBNull(ndx))
           {
            long size = rdr.GetBytes(ndx, 0, null, 0, 0);  //get the length of data
            byte[] values = new byte[size];

            int bufferSize = 1024;
            long bytesRead = 0;
            int curPos = 0;

            while (bytesRead < size)
            {
                bytesRead += rdr.GetBytes(ndx, curPos, values, curPos, bufferSize);
                curPos += bufferSize;
            }
           }
于 2012-06-21T09:30:39.047 に答える