verwendetes Datenbanksystem: MS SQL (2012 und 2014)
Hallo,
ich stehe vor einem Problem, bei dem ich mir nicht mehr zu helfen weiß, auch Google etc. konnte mir leider nicht helfen.
Ich habe eine Tabelle Notizen, in der es eine Spalte des Typs 'Image' (die Datenbank ist schon älter, deshalb wurde hier noch mit 'Image' gearbeitet) mit dem Namen 'Datenfeld' gibt. In diesem Datenfeld sind Blobs/Streams/Binärdaten beliebiger Dateien gespeichert (PDF, DOC etc.). Dieses Datenfeld möchte ich auslesen um den Inhalt wieder als Datei speichern zu können. Der Inhalt von Datenfeld ist ein UTF8 codierter Stream. Soweit so gut.
Ich habe nun folgende Varianten ausprobiert, die auf einem MS SQL Server 2014 auch alle problemlos funktionieren:
Variante 1:
using (SqlConnection connection = new SqlConnection(builder.ConnectionString))
{
connection.Open();
using (SqlCommand command = new SqlCommand("select Notiznr, Datenfeld from Notizen where Notiznr = 1000", connection))
{
using (SqlDataReader reader = command.ExecuteReader(CommandBehavior.SequentialAccess))
{
while (reader.Read())
{
int fieldpos = reader.GetOrdinal("Datenfeld");
if (reader.IsDBNull(fieldpos))
break;
byte[] daten = new byte[]{};
using (MemoryStream mem = new MemoryStream())
{
using (Stream output = reader.GetStream(fieldpos))
{
output.CopyTo(mem);
daten = mem.ToArray();
}
}
}
}
}
connection.Close();
}
Variante 2:
using (SqlConnection connection = new SqlConnection(builder.ConnectionString))
{
connection.Open();
using (SqlCommand command = new SqlCommand("select Notiz, Datenfeld from Notizen where Notiznr = 1000", connection))
{
using (SqlDataReader reader = command.ExecuteReader(CommandBehavior.SequentialAccess))
{
while (reader.Read())
{
int fieldpos = reader.GetOrdinal("Datenfeld");
if (reader.IsDBNull(fieldpos))
break;
long totalbytes = reader.GetBytes(fieldpos, 0, null, 0, 0);
if (totalbytes < 1)
break;
long bytesgelesen = 0;
byte[] daten = new byte[totalbytes];
long startpos = 0;
while (bytesgelesen < totalbytes)
{
bytesgelesen += reader.GetBytes(fieldpos, startpos, daten, (int)startpos, 1024); // tried with several block sizes...
startpos += 1024;
}
}
}
}
connection.Close();
}
Variante 3:
using (SqlConnection connection = new SqlConnection(builder.ConnectionString))
{
connection.Open();
using (SqlCommand command = new SqlCommand("select Datenfeld from Notizen where Notiznr = 1000", connection))
{
byte[] daten = (byte[])command.ExecuteScalar();
}
connection.Close();
}
und Variante 4:
using (SqlConnection connection = new SqlConnection(builder.ConnectionString))
{
connection.Open();
using (SqlCommand command = new SqlCommand("select Notiznr, Datenfeld from Notizen where Notiznr = 1000", connection))
{
using (SqlDataReader reader = command.ExecuteReader(CommandBehavior.SequentialAccess))
{
while (reader.Read())
{
int fieldpos = reader.GetOrdinal("Datenfeld");
if (reader.IsDBNull(fieldpos))
break;
byte[] daten = (byte[])reader[fieldpos];
}
}
}
connection.Close();
}
Nun habe ich die exakt gleiche Datenbank mit zwei verschiedenen MS SQL Server 2012 Installationen ausprobiert und erhalte dort statt der erwünschten Daten immer 20 Bytes, die den Text 'OLE-Objekt' repräsentieren (UTF8, deswegen 20 Bytes). Ich habe auch schon versucht statt der Sql-Klassen mit OleDB zu arbeiten (funktioniert auf dem MS SQL Server 2014 wieder problemlos) aber bekomme immer das gleiche Ergebnis.
Weiß jemand Rat?
Gruß,
wcseller