Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Standardmäßig werden mit dem DataReader eingehende Daten als Zeile geladen, sobald eine ganze Datenzeile verfügbar ist. Binary Large Objects (BLOBs) müssen jedoch anders behandelt werden, da sie mehrere Gigabyte an Daten umfassen können und dann nicht in eine einzelne Zeile passen. Die Command.ExecuteReader-Methode ist überladen, und mit dem CommandBehavior-Argument kann das Standardverhalten des DataReader-Objekts geändert werden. Sie können CommandBehavior.SequentialAccess an die ExecuteReader-Methode übergeben, um das Standardverhalten des DataReaders so zu verändern, dass nicht Datenzeilen, sondern die Daten beim Empfang nacheinander geladen werden. Diese Methode eignet sich ideal zum Laden von BLOBs oder anderen großen Datenstrukturen. Beachten Sie, dass dieses Verhalten je nach Datenquelle verschieden sein kann. Wenn beispielsweise ein BLOB von Microsoft Access zurückgegeben wird, werden die Daten beim Empfang nicht sequenziell geladen, sondern das BLOB wird vollständig in den Speicher geladen.
Wenn Sie SequentialAccess für den DataReader verwenden, müssen Sie die Reihenfolge beachten, in der Sie auf die zurückgegebenen Felder zugreifen. Das Standardverhalten des DataReaders, wonach eine ganze Zeile geladen wird, sobald sie verfügbar ist, ermöglicht es Ihnen, in beliebiger Reihenfolge auf die zurückgegebenen Felder zuzugreifen, bis die nächste Zeile gelesen wird. Bei Verwendung von SequentialAccess müssen Sie jedoch der Reihe nach auf die verschiedenen vom DataReader zurückgegebenen Felder zugreifen. Wenn durch die Abfrage beispielsweise drei Spalten zurückgegeben werden und es sich bei der letzten um BLOB-Werte handelt, müssen Sie die Werte des ersten und zweiten Feldes zurückgeben, bevor Sie auf die BLOB-Daten im dritten Feld zugreifen. Wenn Sie vor dem ersten und zweiten Feld auf das dritte Feld zugreifen, sind die Werte des ersten und zweiten Feldes nicht mehr verfügbar. Dies liegt daran, dass der DataReader mit SequentialAccess geändert wurde und Daten nur noch der Reihe nach zurückgegeben werden. Die Daten sind nicht mehr verfügbar, wenn der DataReader sie "überlesen" hat.
Um auf die Daten im BLOB-Feld zuzugreifen, verwenden Sie GetBytes und GetChars, die typisierten Accessoren des DataReader, die ein Array mit Daten auffüllen. Für Zeichendaten können Sie auch GetString verwenden. Um die Systemressourcen nicht unnötig zu belasten, wird jedoch davon abgeraten, einen ganzen BLOB-Wert in eine einzelne Zeichenfolgenvariable zu laden. Sie können eine bestimmte Puffergröße für Rückgabedaten und die Anfangsposition für das erste zu lesende Byte oder Zeichen in den Rückgabedaten angeben. Mit GetBytes und GetChars wird ein long-Wert zurückgegeben, der der Anzahl der zurückgegebenen Bytes oder Zeichen entspricht. Wenn Sie an GetBytes oder GetChars ein Null-Array übergeben, entspricht der zurückgegebene long-Wert der Gesamtzahl von Bytes oder Zeichen im BLOB. Optional können Sie einen Index im Array als Anfangsposition für die gelesenen Daten angeben.
Das folgende Beispiel gibt die Publisher-ID und das Logo der pubs-Beispieldatenbank in Microsoft SQL Server zurück. Die Publisher-ID (pub_id) ist ein Zeichenfeld, das Logo ist ein Bild und entspricht einem BLOB. Da das logo-Feld eine Bitmap ist, werden im Beispiel Binärdaten mit GetBytes zurückgegeben. Beachten Sie, dass für die aktuelle Datenzeile zuerst auf die Publisher-ID und dann auf das Logo zugegriffen wird, da der Zugriff auf die Felder der Reihe nach erfolgen muss.
Dim pubsConn As SqlConnection = New SqlConnection("Data Source=localhost;Integrated Security=SSPI;Initial Catalog=pubs;")
Dim logoCMD As SqlCommand = New SqlCommand("SELECT pub_id, logo FROM pub_info", pubsConn)
Dim fs As FileStream ' Writes the BLOB to a file (*.bmp).
Dim bw As BinaryWriter ' Streams the binary data to the FileStream object.
Dim bufferSize As Integer = 100 ' The size of the BLOB buffer.
Dim outbyte(bufferSize - 1) As Byte ' The BLOB byte() buffer to be filled by GetBytes.
Dim retval As Long ' The bytes returned from GetBytes.
Dim startIndex As Long = 0 ' The starting position in the BLOB output.
Dim pub_id As String = "" ' The publisher id to use in the file name.
' Open the connection and read data into the DataReader.
pubsConn.Open()
Dim myReader As SqlDataReader = logoCMD.ExecuteReader(CommandBehavior.SequentialAccess)
Do While myReader.Read()
' Get the publisher id, which must occur before getting the logo.
pub_id = myReader.GetString(0)
' Create a file to hold the output.
fs = New FileStream("logo" & pub_id & ".bmp", FileMode.OpenOrCreate, FileAccess.Write)
bw = New BinaryWriter(fs)
' Reset the starting byte for a new BLOB.
startIndex = 0
' Read 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.
Do 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)
Loop
' Write the remaining buffer.
bw.Write(outbyte, 0 , retval - 1)
bw.Flush()
' Close the output file.
bw.Close()
fs.Close()
Loop
' Close the reader and the connection.
myReader.Close()
pubsConn.Close()
[C#]
SqlConnection pubsConn = new SqlConnection("Data Source=localhost;Integrated Security=SSPI;Initial Catalog=pubs;");
SqlCommand logoCMD = new SqlCommand("SELECT pub_id, logo FROM pub_info", pubsConn);
FileStream fs; // Writes the BLOB to a file (*.bmp).
BinaryWriter bw; // Streams the BLOB to the FileStream object.
int bufferSize = 100; // Size of the BLOB buffer.
byte[] outbyte = new byte[bufferSize]; // The BLOB byte[] buffer to be filled by GetBytes.
long retval; // The bytes returned from GetBytes.
long startIndex = 0; // The starting position in the BLOB output.
string pub_id = ""; // The publisher id to use in the file name.
// Open the connection and read data into the DataReader.
pubsConn.Open();
SqlDataReader myReader = logoCMD.ExecuteReader(CommandBehavior.SequentialAccess);
while (myReader.Read())
{
// Get the publisher id, which must occur before getting the logo.
pub_id = myReader.GetString(0);
// Create a file to hold the output.
fs = new FileStream("logo" + pub_id + ".bmp", FileMode.OpenOrCreate, FileAccess.Write);
bw = new BinaryWriter(fs);
// 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();
// Close the output file.
bw.Close();
fs.Close();
}
// Close the reader and the connection.
myReader.Close();
pubsConn.Close();
Siehe auch
Datenzugriff mit .NET Framework-Datenprovidern | Schreiben von BLOB-Werten in eine Datenbank | OleDbDataReader-Klasse | OleDbCommand-Klasse | OdbcDataReader-Klasse | OdbcCommand-Klasse | SqlDataReader-Klasse | SqlCommand-Klasse | CommandBehavior-Enumeration