Announcement

Collapse
No announcement yet.

BlobFeld in ado recordset

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • BlobFeld in ado recordset

    Hallo zusammen,
    <p>
    gesundes neues erstmal
    <p>

    ich versuche krampfhaft, ein Blobs an Crystal Reports zu übergeben (Es sidn selbstgebaute Barcodes, die in keiner DB stehen.
    <br>
    Dazu erzeuge ich mit
    <p>
    <pre>
    FRecordset := CoRecordset.Create;
    FRecordset.CursorLocation := adUseClient;

    FRecordset.Fields.Append('Field1',adBstr,100,adFld Unspecified);
    FRecordset.Fields.Append('Field2',adBstr,100,adFld Unspecified);
    FRecordset.Fields.Append('Field3',adBinary,100,adF ldUnspecified);
    </pre>
    <p>
    ein Ado-Recordset
    <br>danke Herr Kosch
    <br>
    dann kommt das Füllern, was mir nicht gelingen will, der Compiler meckert.
    <br>
    Wie bekomme ich denn nen Blob hier rein ??
    <pre>

    var
    MemStream : TMemoryStream;
    FileStream : TFileStream;
    begin
    FileStream:= TFileStream.Create('d:\user\raja.bmp', fmOpenRead);
    MemStream:= TMemoryStream.Create;
    MemStream.CopyFrom(FileStream, 0);

    FRecordset.Open(EmptyParam,EmptyParam,
    adOpenUnspecified,adLockUnspecified,1);
    FRecordset.AddNew(
    VarArrayOf([
    WideString('Field1'),
    WideString('Field2'),
    WideString('Field3')
    ]),
    VarArrayOf([
    sTest,sTest,MemStream]));

    FRecordset.Update(Emptyparam,EmptyParam);

    </pre>
    <p>
    danke im voraus
    <br>
    Heiko

  • #2
    Hallo,

    das folgende Beispiel demonstriert, wie man BLOb-Daten in diese In-Memory-Tabelle (Recordset-Objektinstanz) bekommt. Mit dem <b>Stream</b>-Objekt von ADO (ab MDAC 2.5) kann man beliebig großen BLOb-Daten bequem verarbeiten. Das folgende Beispiel bindet daher nebe ADODB (Borland) auch die importierte Typbibliotheks-Unit <i>ADODB_TLB</i> ein:

    <pre>
    <b>uses</b> ActiveX, ComObj;

    <b>procedure</b> TForm1.Button1Click(Sender: TObject);
    <b>var</b>
    aADOStream : _Stream;
    <b>begin</b>
    FRecordset := CreateComObject(CLASS_Recordset) <b>as</b> _Recordset;
    FRecordset.CursorLocation := adUseClient;
    FRecordset.Fields.Append(<font color="#9933CC">'Field1'</font>,adVarChar,10,adFldUnspecified);
    FRecordset.Fields.Append(<font color="#9933CC">'Field2'</font>,adVarChar,10,adFldUnspecified);
    FRecordset.Fields.Append(<font color="#9933CC">'Field3'</font>,adLongVarBinary,100000,adFldUnspecified);
    <font color="#003399"><i>// Recordset öffnen</i></font>
    FRecordset.Open(EmptyParam, EmptyParam, adOpenUnspecified,
    adLockUnspecified, 0);
    <font color="#003399"><i>// immediate update mode anfordern (Edit-Modus des Recordset)</i></font>
    OleVariant(FRecordset).AddNew;
    FRecordset.Fields.Item[<font color="#9933CC">'Field1'</font>].Value := <font color="#9933CC">'Test 1'</font>;
    FRecordset.Fields.Item[<font color="#9933CC">'Field2'</font>].Value := <font color="#9933CC">'Test 2'</font>;
    <font color="#003399"><i>// Stream-Objekt von ADO lädt die BLOb-Daten</i></font>
    aADOStream := CoStream.Create;
    aADOStream.Type_ := adTypeBinary;
    aADOStream.Open(EmptyParam, adModeUnknown,
    adOpenStreamUnspecified, <font color="#9933CC">''</font>, <font color="#9933CC">''</font>);
    aADOStream.LoadFromFile(<font color="#9933CC">'C:\WINDOWS\Angler.bmp'</font>);
    FRecordset.Fields.Item[<font color="#9933CC">'Field3'</font>].Value := aADOStream.<b>Read</b>(adReadAll);
    FRecordset.Update(EmptyParam, EmptyParam);
    <font color="#003399"><i>// Ergebnis via TDBGrid und TDBImage anzeigen</i></font>
    ADODataSet1.Recordset := FRecordset;
    ADODataSet1.Open;
    DBImage1.DataField := <font color="#9933CC">'Field3'</font>;
    <b>end</b>;
    </pre>

    Im <i>immediate update mode</i> (AddNew wird <b>ohne</B> Parameter aufgerufen) geht das Recordset in den EditMode <i>adEditAdd</i> und puffert alle Schreibzugriffe solange zwischen, bis die Update-Methode aufgerufen wird. Allerdings gibt es hier in Delphi ein Problem. ADO wurde speziell für ASP und VB-Anwendungen konzipiert, die über die späte Bindung auf die COM-Objekte zugreifen. Beim Weg über die späte Bindung stehen die optionalen Parameter zur Verfügung, d.h. man darf dort AddNew ohne Parameter aufrufen. Das eigene Delphi-Programm greift jedoch in der Regel über die frühe Bindung zu - und hier erzwingt die Typprüfung des Compilers, dass alle Parameter angegeben werden müssen:

    Fall a) späte Bindung: vRS.AddNew <br>
    Fall b) frühe Bindung: aRS.AddNew(EmptyParam, EmptyParam)

    Damit auch in Delphi das von Microsoft dokumentierte Verhalten zur Verfügung steht, muss die späte Bindung für den Methodenaufruf von AddNew verwendet werden:

    OleVariant(aRS).AddNew;

    Bei meinem einfachen Beispiel mit den 3 Spalten funktioniert zwar auch der "normale" aRS.AddNew(EmptyParam, EmptyParam)-Aufruf, aber für den Worst Cast gehe ich immer auf Nummer Sicher.
    &#10

    Comment


    • #3
      Danke Andreas,<p>
      es läuft (bin erst jetzt dazugekommen).
      <p>
      Heik

      Comment

      Working...
      X