Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi Bild in Datenbank speichern - Problem (https://www.delphipraxis.net/167760-bild-datenbank-speichern-problem.html)

Root2k 17. Apr 2012 07:41

Datenbank: MySQL • Version: 5.0.27 • Zugriff über: DevartDBExpress

Bild in Datenbank speichern - Problem
 
Hi,

erstmal die Daten vorweg:

Datenbank: MySQL
Version: 5.0.27
BLOB-Feld: MEDIUMBLOB

Noch eine kleine Info: Ich habe viele Foren durchstöbert und unterschiedliche Wege ausprobiert. Allerdings schaffe ich es nicht, ein Bild in dem BLOB-Feld zu speichern... und genau das ist jetzt mein Problem.

Folgender Code für das Anzeigen von Bildern funktioniert wunderbar (stammt aber von einem Kollegen)...

Delphi-Quellcode:
function TDatabaseConnection.GetImage(query, AField: String;
  var Image: TJpegImage): boolean;
var
  s: TMemoryStream;
begin;
  OpenQuery(query); // query := 'SELECT bild FROM foto WHERE id = 123'
  s := TMemoryStream.Create;
  try
    try
      TBlobField(SQLQuery.FieldByName(AField)).SaveToStream(s); // SQLQuery ist vom Typ TSQLQuery
      s.Position := 0;
      if s.Size > 0 then
      begin
        Image.LoadFromStream(s);
      end;
    except
      on E: Exception do
        ShowMessage('Fehler');
    end;
  finally
    begin
      s.Free;
      FreeAndNil(SQLQuery);
    end;
  end;
end;

Der folgende Code funktioniert nicht! Ich habe selber mal ein bisschen rumprobiert, habe aber ehrlich gesagt auch keine Ahnung wie das wirklich funktioniert oder funktionieren sollte. Forenbeiträge hab ich aber massig gelesen und viel ausprobiert... leider erfolglos.

Speichern von Bildern:
Delphi-Quellcode:
function TDatabaseConnection.SetImage(query, AField: String;): boolean;
var
  s: TMemoryStream;
begin;
  s := TMemoryStream.Create;
  try
    try
      s.LoadFromFile('*BILDPFAD*\*BILDNAME*.jpg');
      s.Position := 0;
      if s.Size > 0 then
      begin
        SQLQuery.Append;
        // Auch mit SQLQuery.Edit noch getestet
        TBlobField(SQLQuery.FieldByName(AField)).LoadFromStream(s);
        SQLQuery.Post;
      end;
    except
      on E: Exception do
        ShowMessage('Fehler');
    end;
  finally
    begin
      s.Free;
      FreeAndNil(SQLQuery);
    end;
  end;
end;
Könnt Ihr mir vielleicht sagen wie ich das umschreiben muss, damit der Code funktioniert? Ich steh momentan absolut auf dem Schlauch und weiß nicht weiter.

Bin für jeden sinnvollen Beitrag dankbar!

DeddyH 17. Apr 2012 07:55

AW: Bild in Datenbank speichern - Problem
 
Ehrlich gesagt verstehe ich den Code auch nicht: von welchem Typ ist SQLQuery und wo kommt das überhaupt her? Wozu 3 Parameter, wenn davon nur einer genutzt wird? Wieso eine Funktion, die immer false zurückgibt?

Root2k 17. Apr 2012 08:12

AW: Bild in Datenbank speichern - Problem
 
- SQLQuery ist vom Typ TSQLQuery (Unit SqlExpr).
- Von den 3 Parametern werden eigentlich schon alle verwendet. Beim Speichern hab ich nachträglich noch ein rausgenommen.
- Der Rückgabewert ist zu vernachlässigen.

DeddyH 17. Apr 2012 08:23

AW: Bild in Datenbank speichern - Problem
 
DBExpress ist nicht mein Gebiet, aber vielleicht geht Folgendes:
- Tabellen- und Feldname als Parameter entgegennehmen, die Grafik natürlich auch
- TSQLDataset/TSQLQuery innerhalb der Funktion anlegen und verbinden
- als SQL "SELECT * FROM Tabellenname WHERE 0" ausführen
- Append
- das BLOB-Feld (Parameter Feldname) befüllen
- Post
- TSQLDataset/TSQLQuery schließen und freigeben

sx2008 17. Apr 2012 08:39

AW: Bild in Datenbank speichern - Problem
 
Also ich sehe in diesem Abschnitt ein Problem:
Delphi-Quellcode:
SQLQuery.Append;
// Auch mit SQLQuery.Edit noch getestet
TBlobField(SQLQuery.FieldByName(AField)).LoadFromStream(s);
SQLQuery.Post;
Man kann nicht einfach einen Datensatz mit einem Blobfeld in eine Tabelle speichern ohne zumindest das Primärschlüsselfeld befüllt zu haben.

Ausserdem würde ich der Funktion nicht eine SQL-Query + Feldname als String übergeben, sondern gleich ein TField-Objekt.
Also z.B. so:
(das .Append und das .Post habe ich entfernt
auch der harte Cast auf TBlobfield war gefährlich
ausserdem wird jetzt auch der Result-Wert befüllt
und das schlechte Exception-Handling was auch unnötig)

Delphi-Quellcode:
function TDatabaseConnection.SetImage(field:TField): boolean;
var
  s: TMemoryStream;
begin;
  s := TMemoryStream.Create;
  try
    s.LoadFromFile('*BILDPFAD*\*BILDNAME*.jpg');
    s.Position := 0;
    result := s.Size > 0;
    if result then
      (field as TBlobField).LoadFromStream(s);
  finally
    s.Free;
  end;
end;

Root2k 17. Apr 2012 09:15

AW: Bild in Datenbank speichern - Problem
 
Danke erstmal für die Beiträge!

Zitat:

Zitat von DeddyH (Beitrag 1162206)
- TSQLDataset/TSQLQuery schließen und freigeben

Wenn ich das mache bekomme ich die Meldung "Eine Datenmenge, die nur zum Lesen ist, kann nicht geändert werden". Also hab ich da ein bisschen gesucht. Da liest man oft "RequestLive auf true setzen". Das TSQLQuery-Objekt besitzt allerdings keine solche Eigenschaft. Auch mit SQLQuery.Edit bin ich nicht weiter gekommen.

Zitat:

Zitat von sx2008 (Beitrag 1162211)
Also ich sehe in diesem Abschnitt ein Problem:

Man kann nicht einfach einen Datensatz mit einem Blobfeld in eine Tabelle speichern ohne zumindest das Primärschlüsselfeld befüllt zu haben.

Das Primärschlüsselfeld ist bereits gesetzt. Nur das BLOB-Feld ist noch zu befüllen.
Den Rest von deinem Beitrag nehm ich gerne zu Kenntnis, aber das hilft mir leider nicht bei dem Problem weiter. Bitte den Code auch nicht als endgültig oder super durchdacht ansehen. Mir geht es nur um die reine Funktionalität!

DeddyH 17. Apr 2012 10:12

AW: Bild in Datenbank speichern - Problem
 
Ginge das mit einer parametrisierten Query nicht einfacher? Wobei ich wie gesagt mit DBExpress nicht vertraut bin.

Root2k 17. Apr 2012 11:57

AW: Bild in Datenbank speichern - Problem
 
Ehrlich gesagt versteh ich da jetzt nicht so richtig wie du das meinst.
kannst du mir vielelicht ein simples Code-Beispiel geben?

Ich probier es jetzt auch mal mit anderen Komponenten... z.B. TSimpleDataSet. Vielleicht komme ich da weiter. Allerdings hab ich mit den ganzen Datenbank-Komponenten keine Erfahrung. :(

DeddyH 17. Apr 2012 12:12

AW: Bild in Datenbank speichern - Problem
 
Ich dachte in etwa so:
Delphi-Quellcode:
procedure SavePictureToDB(ID: integer; const Filename: string);
begin
  SQLQuery.SQL.Text := 'UPDATE Tabelle SET Feld = :wert WHERE ID = :id';
  SQLQuery.ParamByName('id').Value := ID;
  SQLQuery.ParamByName('wert').LoadFromFile(Filename);
  SQLQuery.ExecSQL;
end;
Ungetestet.

Root2k 17. Apr 2012 12:34

AW: Bild in Datenbank speichern - Problem
 
Ungetestet, aber funktioniert wunderbar :-D

Nur eine Zeile hat noch nicht ganz gestimmt:
Delphi-Quellcode:
SQLQuery.ParamByName('wert').LoadFromFile(Filename, ftBlob);


Aber klappt super! Danke dir vielmals!! :thumb::thumb::thumb:

*closed*


Alle Zeitangaben in WEZ +1. Es ist jetzt 19:42 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz