Delphi-PRAXiS
Seite 3 von 3     123   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi Bild in MySQL (Blob) mit mysql.pas speichern (https://www.delphipraxis.net/19823-bild-mysql-blob-mit-mysql-pas-speichern.html)

hoika 21. Feb 2020 14:33

AW: Bild in MySQL (Blob) mit mysql.pas speichern
 
Hallo,
ah, Lesefehler.
Ich würde statt dem String einen TStringStream benutzen.

Datei -> TFileStream -> TStringStream -> TStringStream.DataString enthält dann die Datei.

PS1: Du solltest auch Stream.Size mal prüfen, das sollte einen Wert > 0 haben.
PS2: FileStream.Position vor allen Aktionen auf 0 setzen (Vielleicht ist das bei Deinem alten Code schon die Lösung).

haentschman 21. Feb 2020 14:45

AW: Bild in MySQL (Blob) mit mysql.pas speichern
 
Hallöle...8-)
Nur aus Neugier...was hat die Fichtner MySQL.pas anders als andere (FireDAC etc.) Blob ist Blob. Oder?

hoika 21. Feb 2020 14:53

AW: Bild in MySQL (Blob) mit mysql.pas speichern
 
Hall,
die Fichtner-Version ist älter,
damit sind wahrscheinlich so etliche MySQL-Anbindungen in Delphi programmiert worden.

17-Aug-1999 mf Translated mysql.h MySQL 3.22.24

samso 21. Feb 2020 15:40

AW: Re: Bild in MySQL (Blob) mit mysql.pas speichern
 
Zitat:

Zitat von Morfio (Beitrag 139012)
Hallo nochmal,

in dem folgenden Abschnitt muß noch irgendwo ein Fehler sein, denn MySQLCC und PHP sagen mir beide, dass das gespeicherte Bild fehlerhaft ist:

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
   Stream: TFileStream;
    S: String;
    query: String;
begin
   Stream := TFileStream.Create(ExtractFilePath(ParamStr(0)) + 'test.jpg', fmOpenRead or fmShareDenyNone);
    try
       SetLength(S, Stream.Size);
       Stream.Read(S, Stream.Size);
    finally
       Stream.Free;
    end;
   query := 'INSERT INTO Bild (Name, Bild) VALUES (' + QuotedStr('testbild') + ', ' + QuotedStr(S) + ')';
    mysql_real_query(myCon, PChar(query), Length(query));
end;
Das kann ja eigentlich kein großer Fehler mehr sein. Woran könnte es denn vielleicht noch liegen?

Vielen Dank,

Morfio ...

PS: Das Bild "test.jpg" ist nicht fehlerhaft, IrfanView kann es ohne Probleme vollständig anzeigen.

Probiere mal "QuoteString" aus der mysql.pas statt QuotedStr.

Benutzt Du noch eine ältere Delphi-Version(<=Delphi 2007)?

himitsu 21. Feb 2020 16:57

AW: Re: Bild in MySQL (Blob) mit mysql.pas speichern
 
Das QuoteStr von Delphi war sowieso noch niemals für SQL vorgesehen, denn es arbeitet nach Standard der Pascal-Strings, also behandelt ausschließlich das '
und vor allem ein \ oder Steuerzeichen machen danach weiterhin viel Spaß.

Außerdem wird es hier ab Delphi 2009 schön knallen, wenn man Binärdaten in einen String/UnicodeSting packt, denn Dabei werden natürlich Bytes verändert, entsprechend der aktuellen Systemsprache (ANSI>Unicode)
https://www.delphipraxis.net/203328-...ifizieren.html

haentschman 22. Feb 2020 07:11

AW: Bild in MySQL (Blob) mit mysql.pas speichern
 
Moin...:P
Zitat:

die Fichtner-Version ist älter
Aus welchem Grund kommt ein Umstieg auf was Aktuelles nicht in Frage? :gruebel:

hoika 22. Feb 2020 07:40

AW: Bild in MySQL (Blob) mit mysql.pas speichern
 
Hallo,
Zitat:

Aus welchem Grund kommt ein Umstieg auf was Aktuelles nicht in Frage?
Das war nur der erste Eintrag im Changelog.
Ich wollte damit zeigen, dass bereits so früh begonnen hatte.

jus 27. Feb 2020 00:32

AW: Re: Bild in MySQL (Blob) mit mysql.pas speichern
 
Ich habe es nun mit einem Prepared Statement gelöst. Für den Fall, dass jemand auch das mal braucht, das folgende Beispiel basiert auf das Prepared Statement Demo "StmtDemo", das im aktuellen mysql.pas ZIP dabei ist.
Delphi-Quellcode:
procedure TForm1.Button3Click(Sender: TObject);
var
  stmt: PMYSQL_STMT;
  bind: PMYSQL_BIND;
  affected_rows: my_ulonglong;
  param_count: Integer;
  InsertQuery: String;
  fs: TFileStream;
  data: array of byte;
  filesize: Int64;
begin
  Memo.Lines.Add('mysql_stmt_init()');
  stmt := mysql_stmt_init(LibHandle);
  if (stmt=nil)
  then begin
    Memo.Lines.Add('mysql_stmt_init(), out of memory');
    exit;
  end;
  Memo.Lines.Add('mysql_stmt_init() done');

  InsertQuery := 'INSERT INTO testblob(filedata) VALUES(?)';

  Memo.Lines.Add('mysql_stmt_prepare()');
  if (mysql_stmt_prepare(stmt, PAnsiChar(InsertQuery), Length(InsertQuery))<>0)
  then begin
    Memo.Lines.Add('mysql_stmt_prepare(), INSERT failed');
    Memo.Lines.Add(mysql_stmt_error(stmt));
  end;
  Memo.Lines.Add('mysql_stmt_prepare() done');

  Memo.Lines.Add('mysql_stmt_param_count()');
  param_count := mysql_stmt_param_count(stmt);
  Memo.Lines.Add(Format('total parameters in INSERT: %d', [param_count]));
  if (param_count <> 1)
  then begin
    Memo.Lines.Add('invalid parameter count returned by MySQL');
    exit;
  end;

  bind := mysql_bind_init(1); //** Different to org. Demo: Alloc 3 MYSQL_BIND **
  try
    fs := TFileStream.Create('TestDatei1.txt',fmOpenRead);
    try
      SetLength(data,fs.Size);
      fs.ReadBuffer(data[0],fs.Size);
      filesize := fs.Size;
    finally
      fs.Free;
    end;

    mysql_bind_set_param(bind, 0, MYSQL_TYPE_BLOB, @data[0], filesize, @filesize, nil);
    Memo.Lines.Add('mysql_stmt_bind_param()');
    if mysql_stmt_bind_param(stmt, bind)
    then begin
      Memo.Lines.Add('mysql_stmt_bind_param() failed');
      Memo.Lines.Add(mysql_stmt_error(stmt));
      exit;
    end;
    Memo.Lines.Add('mysql_stmt_bind_param() done');

    Memo.Lines.Add('mysql_stmt_execute()');
    if (mysql_stmt_execute(stmt)<>0)
    then begin
      Memo.Lines.Add('mysql_stmt_execute() failed');
      Memo.Lines.Add(mysql_stmt_error(stmt));
      exit;
    end;
    Memo.Lines.Add('mysql_stmt_execute() done');
    affected_rows := mysql_stmt_affected_rows(stmt);
    Memo.Lines.Add(Format('total affected rows(insert 2): %u', [affected_rows]));
    if (affected_rows <> 1)
    then begin
      Memo.Lines.Add('invalid affected rows by MySQL');
      exit;
    end;

  finally
    FreeMem(bind);
  end;
  if mysql_stmt_close(stmt)
  then begin
    Memo.Lines.Add('failed while closing the statement');
    Memo.Lines.Add(mysql_stmt_error(stmt));
    exit;
  end;
end;
Wobei die testblob Tabelle wie folgt ausschaut:
Code:
CREATE TABLE `testblob` (
  `id` int(11) NOT NULL auto_increment,
  `filename` varchar(200) default NULL,
  `filesize` int(11) default NULL,
  `filedata` longblob,
  PRIMARY KEY (`id`));
Zitat:

Zitat von samso (Beitrag 1458064)
Benutzt Du noch eine ältere Delphi-Version(<=Delphi 2007)?

ja, bei diesem Projekt immer noch Delphi 2007.


Alle Zeitangaben in WEZ +1. Es ist jetzt 14:14 Uhr.
Seite 3 von 3     123   

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