Sonntag, 7. September 2008

entwickler.com Magazine Konferenzen Akademie Entwickler-Forum Jobbörse Bücher
Software & Support Verlag

_Recordset und Blob

Frage: Ich verwende ein Recordset (ADO) um auf Daten zuzugreifen. Wie kann ich dort aber BLOb-Daten auslesen und als Datei speichern?

Antwort: Mit der ADO-Version 2.5 hat Microsoft zusätzlich zum Record-Objekt das Stream-Objekt neu in das ADO-Objektmodell eingeführt. Mit diesem Objekt vereinfacht sich der Zugriff auf BLOb-Daten (Binary Large Objects), da das Hantieren mit den alten Methoden GetChunk und AppendChunk nicht mehr notwendig ist. Mit dem neuen Objekt ist auch das vorherige Bestimmen der BLOb-Grösse nicht mehr notwendig, so dass sich der Einsatz im Alltag spürbar vereinfacht. Dies gilt auch dann, wenn ohne ADO Express (alias dbGo) direkt auf die nativen ADO-Objekte zugegriffen wird.

Im folgenden Beispiel wird der Inhalt einer Datei eingelesen und als binärer Inhalt in einer Image-Spalte einer SQL Server 7/2000-Datenbanktabelle abgelegt. Dazu öffnet das Beispiel über eine „unsinnige“ SELECT-Abfrage mit der WHERE-Einschränkung 1 = 0 eine garantiert leere Datenmenge im Recordset, so dass über den Aufruf der Recordset-Methode AddNew gleich ein neuer Datensatzpuffer angefordert werden kann. Über die Fields-Kollektion des Recordset-Objekts übergibt das Programm die Daten für beide Spalten des neuen Datensatzes, so dass dieser Datensatz über den Aufruf von Update in der Tabelle abelegt wird. Anschliessend liest das Programm den gespeicherten Inhalt über eine SELECT-Abfrage neu ein und speichert diese Daten unter einem anderen Dateinamen wieder ab. Wird dazu eine neue Instanz des Stream-Objekts erzeugt, kann dieses über die Write-Methode die als Parameter übergebenen Daten in den eigenen Stream schreiben. Ist das erledigt, speichert der Aufruf von SaveToFile diese Streamdaten in einer Datei ab.

procedure TForm1.ToolButtonBLOBClick(Sender: TObject);
resourcestring
  RS_SQL = 'SELECT ID, FileContents FROM StreamBLOBDemo WHERE 1 = 0';
  SELECT = 'SELECT ID, FileContents FROM StreamBLOBDemo WHERE ID = ';
var
  aADOStream : _Stream;
  aRS        : _RecordSet;
  iID        : Integer;
  vSQL       : OleVariant;
begin
  // Step 1: ADO-Stream-Objekt initialisieren
  aADOStream := CoStream.Create;
  aADOStream.Type_ := adTypeBinary;
  aADOStream.Open(EmptyParam, adModeUnknown,
                  adOpenStreamUnspecified, '', '');
  aADOStream.LoadFromFile(FFileName);
  // Step 2: ADO-Recordset-Objekt initialisieren
  aRS := CoRecordset.Create;
  aRS.CursorLocation := adUseClient;
  vSQL := RS_SQL;
  aRS.Open(vSQL, ADOConnection1.ConnectionObject,
           adOpenStatic, adLockOptimistic, adCmdText);
  // Step 3: Neuen Datensatzpuffer anfordern
  aRS.AddNew(EmptyParam, EmptyParam);
  iID := StrToInt(EditID.Text);
  // Step 4: Werte zuweisen, BLOb aus Stream-Objekt zuordnen
  aRS.Fields.Item['ID'].Value := iID;
  aRS.Fields.Item['FileContents'].Value := aADOStream.Read(adReadAll);
  // Step 5: Datensatz speichern
  aRS.Update(EmptyParam, EmptyParam);
  aRS.Close;
  aADOStream.Close;
  aRS := nil;
  aADOStream := nil;
  // Step 6: Datensatz zur Kontrolle neu einlesen
  aRS := CoRecordset.Create;
  vSQL := SELECT + IntToStr(iID);
  aRS.Open(vSQL, ADOConnection1.ConnectionObject,
           adOpenForwardOnly, adLockReadOnly, adCmdText);
  // BLOb-Inhalt via Stream-Objekt auslesen und speichern
  aADOStream := CoStream.Create;
  aADOStream.Type_ := adTypeBinary;
  aADOStream.Open(EmptyParam, adModeUnknown,
                  adOpenStreamUnspecified, '', '');
  aADOStream.Write(aRS.Fields.Item['FileContents'].Value);
  aADOStream.SaveToFile(FSaveFileName, adSaveCreateOverWrite);
  aADOStream.Close;
  aRS.Close;
  Inc(iID);
  EditID.Text := IntToStr(iID);
end;






Software & Support Verlag GmbH