Announcement

Collapse
No announcement yet.

Blob-Datenfelder und Stringvariablen

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

  • Blob-Datenfelder und Stringvariablen

    Hallo,

    Ich habe in einer Interbase-Tabellenstruktur ein Blobfeld.

    Kann mir jemand auf die Schnelle ein Beispiel geben, wie ich diesem Blobfeld den Inhalt einer Stringvariable (oder mehreren Stringvariablen, jede Stringvariable soll eine eigene Zeile sein), per Programmcode mittels Query zur Laufzeit zuweisen kann.

    Ebenso den umgekehrten Weg, den Inhalt des Blobfeldes in Stringvariabl(e) einlesen.

    Vielen Dank

    Helmut

  • #2
    Hallo,

    <b>Gibt es niemanden</b>, der ein derartiges Beispiel schon programmiert hat ?

    In der Literatur sind auch keinerlei Beispiele hiezu zu finden.

    Es muß doch möglich sein, einem Blobfeld per Query einen Stringwert zuzuweisen (Insert oder Update). Meine bisherigen Versuche sind jedoch kläglich gescheitert.

    Gruss aus Wien, Helmu

    Comment


    • #3
      Hallo,

      das folgende Beispiel stammt aus meinem Buch <b>Client/Server-Datenbankentwicklung mit Delphi</b>. Es speichert den komprimierten Inhalt von eingelesenen Dateien in einem BLOB-Feld in einer InterBase-Datenbank ab. Dazu wird die Datei in einen MemoryStream gelesen und mit <b>ZLIB</b> (von der Delphi-CDROM) komprimiert. In der TQuery-Instanz wird eine INSERT-Anweisung mit einem BLOB-Parameter ausgeführt. Der Parameterwert wird dabei über <b>LoadFromStream</b> zugewiesen:
      <pre>
      ParamByName('bFileData').LoadFromStream(OutFile, ftBlob);
      </pre>
      Das Auslesen des BLOB-Inhaltes einer SELECT-Abfrage erfolgt dann auf dem umgekehrten Weg. Um den Dateiinhalt anzuzeigen, wird im TMemo über die Eigenschaft <b>Lines</b> die Methode <B>LoadFromStream</b> aufgerufen. Hinter <i>QuerySelectBlobFILEDATA</i> verbirgt sich die persistente TField-Instanz für die BLOB-Spalte der SELECT-Abfrage:
      <pre>
      var
      InFile : TBlobStream;
      OutFile : TStream;
      ZStream : TCustomZLibStream;
      Count : Integer;
      begin
      with QuerySelectBlob do begin
      Params[0].Value := QueryProFilesFILENR.Value;
      Open;
      end;
      InFile := TBlobStream.Create(QuerySelectBlobFILEDATA, bmRead);
      ...
      Memo1.Lines.LoadFromStream(OutFile);
      ...
      </pre&gt

      Comment


      • #4
        <b>An Herrn Andreas Kosch</b>

        Vielen Dank für Ihre Beantwortung. Ich habe noch ein paar Fragen.
        Ich besitze fast alle Ihre Bücher, jedoch das besagte Buch noch nicht.

        Warum wurde <b>ZStream</b> und <b>Count</b> deklariert ?<br>
        Was bedeutet der Bezeichner <b>QueryProFilesFILENR</b> ?<br>
        Die beiden letzten Programmzeilen: Wie kommt die Verbindung zwischen Infile und OutFile zustande ? Es wurde ja nur in InFile eingelesen.

        <b>Meine gewünschte Anwendung:</b><br>
        Ich möchte nur ein paar Stringkonstanten (nur im Quelltext enthalten) dem Blobfeld zuweisen.
        Gibt es eine Möglichkeit dies direkt im Memory zu tun, ohne den Umweg über eine Datei zu gehen ? Zuerst die Stringkonstanten in eine Datei zu speichern (pro Konstante wäre hier eine Datei erforderlich, da es sich meist um verschiedene Blobfelder handelt), um diese dann nachher einlesen zu können, wäre ein großer Aufwand.

        Wenn Sie ein Beispiel haben, ersuche ich Sie höflichst um den kompletten Quelltext.

        z.B.

        <b>const</b>>br>
        S1 = 'Demotext 1.Zeile'; <br>
        S2 = 'Zweite Zeile für gleiches BlobFeld';<br>

        begin<br>
        with Query1 do begin<br>
        // Zuweisung des Textes an die Parametervariable<br>
        ParamByName['bTextData'].LoadFrom??? <br>
        Open;<br>
        end;<br>

        Die beiden Stringkonstanten (bzw. eine Stringvariable) sollen einem Blobfeld zugewiesen werden. Jede Konstante entspricht einer Textzeile.

        Wie schaut hier die Query-Prozedur aus. Wie wird die Parametervariable angesprochen ?

        Vielen Dank
        Helmu

        Comment


        • #5
          Hallo,

          >Warum wurde ZStream und Count deklariert ?

          Wie ich in meiner Antwort bereits sagte, speichere ich den eingelesenen Dateiinhalt erst dann in der Datenbank ab, wenn dieser über <b>ZLIB</b> komprimiert wurde. Dies ist aber nur eine zusätzliche Option und hat nichts mit dem BLOb-Parameter zu tun.

          >Was bedeutet der Bezeichner QueryProFilesFILENR ?

          Das ist ein <b>persistens TField</b>, d.h. in Delphi wurde für die TQuery-Instanz "QueryProFiles" für die Tabellenspalte "FILENR" ein TField über den <b>Feld-Editor</b> fest eingerichtet, damit diese Spalte visuell im Objektinspektor konfiguriert werden kann.

          >Wenn Sie ein Beispiel haben, ersuche ich Sie höflichst um den kompletten Quelltext.

          Das originale Beispielprojekt ist zu umfangreich, daher verwende ich nun eine übersichtlichere Version. Das folgende Programm speichert Icons (*.ICO) als BLOb in einer Datenbank und liest diese wieder aus. Die INSERT-Anweisung für das Abspeichern sieht wie folgt aus:
          <pre>
          QueryICON.SQL = INSERT INTO icondb (Name, Icon)
          VALUES (:sName, :bIcon)

          QueryICON.Params = sName : String
          bIcon : Blob
          </pre>
          Zur Vereinfachung verzichte ich hier auf persistente TFields, so das die Parameter über ihre Position übergeben werden:
          <pre>
          procedure TFormMain.BitBtnImportClick(Sender: TObject);
          begin
          with QueryIcon do
          begin
          Params[0].AsString := EditIconName.Text;
          if StaticTextPath.Caption <> '' then
          begin
          Params[1].LoadFromFile(OpenPictureDialog1.FileName, ftGraphic);
          ExecSQL;
          end;
          end;
          end;
          </pre>
          Das Ereignis <b>TDataSource.OnDataChange</b> signalisiert einen Datensatzwechsel. Da die TDBImage-Komponente keine Icon's anzeigen kann, muss die normale TImage-Komponente (TImage.Picture.Icon) verwendet werden. Via TBlobSteam "fliesst" das Icon von einem Arbeitsspeicherbereich in den anderen. Allerdings wird hier ein <b>persistentes TField</b> für die BLOb-Spalte der Datenbanktabelle benötigt, daher muss <i>TableIconTableICON</i> als TBlobField-Instanz angesprochen werden.
          <pre>
          procedure TFormMain.DataSource1DataChange(Sender: TObject; Field: TField);
          var
          aStream: TBlobStream;
          begin
          with TableIconTable do
          begin
          // Wieviel Icons sind im Bestand ?
          StatBar.SimpleText := Format('%d Datensätze vorhanden', [RecordCount]);
          // kein Datensatz -> Abbruch
          if RecordCount = 0 then Exit;
          end;
          // TDBImage kann nur Bitmaps, daher dieser Umweg
          aStream := TBlobStream.Create(TableIconTableICON as TBlobField, bmRead);
          try
          ImageDB.Picture.Icon.LoadFromStream(aStream);
          finally
          aStream.Free;
          end;
          end;
          </pre&gt

          Comment

          Working...
          X