![]() |
Datenbank: MySQL • Version: 5.9xxx • Zugriff über: Firedac
Parameter unter Firedac
Hi zusammen
Das hier ist eine der Proceduren, die ablaufen, wenn ein Bild in meine DB aufgenommen werden soll. Eingeführt wurde sie unter DBExpress; Jetzt, unter Firedac, hab ich bis auf das beteiligte Query nichts geändert. Auch in den andern Proceduren nicht. Und es tut genau, was es soll. In den letzten Tagen habe ich wohl beinahe "jeden Stein umgedreht" nach der Suche, wie Firedac mit Abfrageparametern umgeht. Die entsprechenden Codebeispiele von Embarcadero arbeiten alle mit "ParamsByName.(..).add." ohne die Parameter (oder wenigstens die Parameter-Collection) vorher zu erzeugen. Auch in den Sourcen habe ich keinen Hinweis darauf gefunden, dass und wo die Params-Collection erzeugt werden. Und da selbst Delphi es nicht schafft, mit nichterzeugten Objekten zu arbeiten ( :wink:):
Delphi-Quellcode:
Gruss
procedure TFDMySQLDml.kategorien_bildDescribeTabelleInsert(BildDescribeLastID: Integer;bildtabelle_idbild: Integer);
var kategorien_tabelle_Kath_ID, BildDescribeTabelle_BilddesribeID, BildDescribeTabelle_Bildtabelle_idBild: Integer; SQLString: String; begin kategorien_tabelle_Kath_ID := ApplicationManager.CategoryKey; BildDescribeTabelle_BilddesribeID := BildDescribeLastID; BildDescribeTabelle_Bildtabelle_idBild := bildtabelle_idbild; SQLString := 'Insert Into kategorien_tabelle_has_bildDescribeTabelle'+ '(kategorien_tabelle_Kath_ID,'+ 'BildDescribeTabelle_BilddesribeID,' + 'BildDescribeTabelle_Bildtabelle_idBild) ' + 'Values (:kategorien_tabelle_Kath_ID,' + ':BildDescribeTabelle_BilddesribeID,' + ':BildDescribeTabelle_Bildtabelle_idBild)'; if (FDQueryMain.Active) then FDQueryMain.Active := False; FDQueryMain.SQL.Text := SQLString; FDQueryMain.Params.CreateParam(ftinteger, 'kategorien_tabelle_Kath_ID', ptInput); FDQueryMain.Params.CreateParam(ftInteger, 'BildDescribeTabelle_BilddesribeID', ptInput); FDQueryMain.Params.CreateParam(ftInteger, 'BildDescribeTabelle_Bildtabelle_idBild', ptInput); FDQueryMain.Params[0].AsInteger := kategorien_tabelle_Kath_ID; FDQueryMain.Params[1].AsInteger := BildDescribeTabelle_BilddesribeID; FDQueryMain.Params[2].AsInteger := BildDescribeTabelle_Bildtabelle_idBild; FDQueryMain.ExecSQL(false); FReportList.Add(' -TPicAdmin.kategorien_bildDescribeTabelleInsert'); end; Delbor |
AW: Parameter unter Firedac
Die Parameter werden erzeugt in
Delphi-Quellcode:
FireDAC.Phys.SQLPreprocessor.TFDPhysPreprocessor.Execute
|
AW: Parameter unter Firedac
Fast alle DBZugriffskomponenten sollten die Parameter selber ertstellen, anhand des übergebenen SQL.
Außer man hat diese Funktion deaktiviert, wo die Komponente das SQL parst, nachdem es zugewiesen/geändert wurde.
Delphi-Quellcode:
FDQueryMain.SQL.Text := SQLString;
FDQueryMain.Params[0].AsInteger := kategorien_tabelle_Kath_ID; FDQueryMain.Params[1].AsInteger := BildDescribeTabelle_BilddesribeID; FDQueryMain.Params[2].AsInteger := BildDescribeTabelle_Bildtabelle_idBild; FDQueryMain.ExecSQL(false); // oder FDQueryMain.SQL.Text := SQLString; FDQueryMain.ParamByName('kategorien_tabelle_Kath_ID').AsInteger := kategorien_tabelle_Kath_ID; FDQueryMain.ParamByName('BildDescribeTabelle_BilddesribeID').AsInteger := BildDescribeTabelle_BilddesribeID; FDQueryMain.ParamByName('BildDescribeTabelle_Bildtabelle_idBild').AsInteger := BildDescribeTabelle_Bildtabelle_idBild; FDQueryMain.ExecSQL(false); |
AW: Parameter unter Firedac
Und speziell FireDAC hat da schöne Überladungen, so dass man auch mit ganz wenig Code auskommt.
Delphi-Quellcode:
Query.ExecSQL('INSERT INTO Tabelle(Feld1, Feld2, Feld3) VALUES(:Wert1, :Wert2, :Wert3)', [1, 2, 3], [ftInteger, ftInteger, ftInteger]);
|
AW: Parameter unter Firedac
Hi zusammen
Vielen Dank für eure aufschlussreichen Antworten! Zitat:
Delphi-Quellcode:
nichts gefunden habe...
C:\Program Files (x86)\Embarcadero\Studio\16.0\source\data\firedac\stan\param
@DeddyH: Zitat:
Und wenn ich mehrere Zeilen draus mache, gehts übersichtlicher wirklich nicht mehr, ist aber immer noch viel kleiner:
Delphi-Quellcode:
Wobei Gruppe 3 offenbar die Indexes enthält. Ich werde das gleich hier mal umsetzen und auch die andern Prozeduren anpassen. Auch wenn das Ding genau(?) das getan hat, was es soll: die "Createparams" von DBExpress sind nicht nur überflüssig, sondern auch zuviel des Guten.
Query.ExecSQL('INSERT INTO Tabelle(Feld1, Feld2, Feld3),'+
' VALUES(:Wert1, :Wert2, :Wert3)', [1, 2, 3], [ftInteger, ftInteger, ftInteger]); Zitat:
Das FDQuery (Unter anderen) hat ein entsprechendes Boolean-Property - dessen Name hab ich inzwischen vergessen. Aber irgendwie ist es mir och lieber, ich übergebe die Parameter selber. Ist vielleicht etwas mehr Typarbeit, dafür ist klar, was abläuft. Gruss Delbor |
AW: Parameter unter Firedac
Zitat:
statt
Delphi-Quellcode:
ist natürlich
[1, 2, 3]
Delphi-Quellcode:
gemeint.
[kategorien_tabelle_Kath_ID, BildDescribeTabelle_BilddesribeID, BildDescribeTabelle_Bildtabelle_idBild]
Zitat:
Delphi-Quellcode:
Gut, FireDAC wird bei falschen Typen nicht meckern können, aber spätestens das DBMS wird es dann tun.
FDQueryMain.SQL.Text := SQLString;
FDQueryMain.ParamByName('kategorien_tabelle_Kath_ID').AsInteger := kategorien_tabelle_Kath_ID; FDQueryMain.ParamByName('BildDescribeTabelle_BilddesribeID').AsInteger := BildDescribeTabelle_BilddesribeID; FDQueryMain.ParamByName('BildDescribeTabelle_Bildtabelle_idBild').AsInteger := BildDescribeTabelle_Bildtabelle_idBild; FDQueryMain.ExecSQL(false); |
AW: Parameter unter Firedac
Aus der Hilfe:
Zitat:
|
AW: Parameter unter Firedac
Hi zusammen
Sorry, wenn ich erst jetzt antworte - ich bin im Moment sozusagen im "MultitaskModus". Im Schweizer Fernsehen läuft geradwe eine Sendung, in der Leute aus Stein im Kanton Appenzell Ferien in der Wohnung eines deutschen Ehepaars in Stein an der Nordsee machen und umgekehrt... @Himitsu: Unter der automatischen ![]() Zitat:
Delphi-Quellcode:
würde, wenn ich das jetzt nicht gründlich missverstanden habe:
SQLString := 'Insert Into Bildtabelle(Thumbnail) Values (:LThumbMemory)';
FDQueryMain.SQL.Text := SQLString; FDQueryMain.Params.CreateParam(ftBlob, 'LThumbMemory', ptInput); FDQueryMain.Params[0].LoadFromStream(LThumbMemory, ftgraphic); FDQueryMain.ExecSQL(false);
Delphi-Quellcode:
Da wird zwar die Variable übergeben. Aber allein aus diesen Zeilen geht nicht hervor, ob die auch wirklich parametrisiert werden.
SQLString := 'Insert Into Bildtabelle(Thumbnail) Values (:LThumbMemory)';
FDQueryMain.SQL.Text := SQLString; FDQueryMain.ExecSQL(false); Gruss Delbor |
AW: Parameter unter Firedac
Es bedeutet ganz einfach, dass FireDAC nach Zuweisen des SQL-Strings nach Parametern sucht, welche als
Delphi-Quellcode:
deklariert sind und dann macht FireDAC das Params.CreateParam, für die gefundenen Parameter (nur halt Typlos, da es den DataTyp ja nicht kennt)
:ParamName
Delphi-Quellcode:
SQLString := 'Insert Into Bildtabelle(Thumbnail) Values (:LThumbMemory)';
FDQueryMain.Options.ParamCreate := False; // oder irgendwie so FDQueryMain.SQL.Text := SQLString; FDQueryMain.Params.CreateParam(ftBlob, 'LThumbMemory', ptInput); FDQueryMain.ParamByName('LThumbMemory').irgendwas...; // oder FDQueryMain.Params[0].irgendwas...; FDQueryMain.ExecSQL(false);
Delphi-Quellcode:
SQLString := 'Insert Into Bildtabelle(Thumbnail) Values (:LThumbMemory)';
FDQueryMain.Options.ParamCreate := True; // oder irgendwie so FDQueryMain.SQL.Text := SQLString; //FDQueryMain.Params.CreateParam(ftBlob, 'LThumbMemory', ptInput); // das macht FireDAC für dich FDQueryMain.ParamByName('LThumbMemory').irgendwas...; // oder FDQueryMain.Params[0].irgendwas...; FDQueryMain.ExecSQL(false); |
AW: Parameter unter Firedac
Hi himitsu
Vielen Dank! Das macht die Sache klarer! Ich dachte wirklich, der sucht das ':' und setzt den Parameter dann auch gleich ein! Auffallend ist/finde ich, dass in allen Beispielen ParambyName verwendet wird und nicht der Feldindex, wobei sich Embarcadero da ja eindeutig ausspricht: treten zwei gleiche Parameternamen auf, wird der erste verwendet und der zweite fallengelassen. Dabei galt schon unter der altehrwürdigen BDE der Weg über die FeldIndexes als der Sicherere. Gruss Delbor |
AW: Parameter unter Firedac
Der Index geht zwar schneller, aber wenn du z.B. mal am SQL was veränderst, dann ändert sich auch der Index, aber über den Namen gibt es niemals Probleme und im Code siehst auch schneller wo auf was zugegriffen wird.
Man nimmt ja auch meistens FieldByName und nicht Fields, wenn man auf die Felder zugreift. Fallen gelassen wird nichts. Der Parser geht von vorne nach hinden durch den String und die Parameter werden in der Reihenfolge in die Liste eingetragen, wie sie gefunden werden. Kommt ein Parameter mehrmals im String vor, dann steht natürlich nur der "erste" Fund an seiner Stelle in der Liste und die nachfolgenden Funde werden nicht nochmal angehängt, da der Parameter dann ja schon existiert. :zwinker:
SQL-Code:
SELECT :a, :b, :a, :c
Delphi-Quellcode:
Params[0] = ParamByName('a')
Params[1] = ParamByName('b') Params[2] = ParamByName('c')
SQL-Code:
SELECT :c, :b, :a, :a
Delphi-Quellcode:
Params[2] = ParamByName('a')
Params[1] = ParamByName('b') Params[0] = ParamByName('c') |
AW: Parameter unter Firedac
Liste der Anhänge anzeigen (Anzahl: 4)
Hi zusammen
Zitat von Sir Rufo: Zitat:
Ich häng hier einige jpegs an, die hoffentlich meine Suche etwas dokumentieren können. Gruss Delbor PS: Da muss ich wohl ziemlich geschlafen haben: Zitat:
|
AW: Parameter unter Firedac
Diese Klasse/Unit ist auch in Seattle nicht dokumentiert.
Nimm doch einfach den Debugger und stepp durch den Code. Wenn dir das zu langweilig ist, dann suche die Parameter-Klasse und setze einen Breakpoint im
Delphi-Quellcode:
. Wenn dann dort angehalten wird, gehst du einfach durch den Callstack durch und findest die Stellen, die das aufrufen.
Create
So mache ich das wenigtens und das führt eigentlich immer zum Erfolg. |
AW: Parameter unter Firedac
Hi zusammen
Zitat:
Delphi-Quellcode:
Ursprünglich hatte ich den Datentyp für das Feld mit ftguid angegeben, aber da meckerte Delphi einige seltsame (unbekannte) Zeichen an.
function TFDMySQLDml.BildInsertQuery(LThumbMemory: TMemoryStream; LFolderID: TMemoryStream): integer;
var SQLString: string; AUser,APass :string; begin SQLString := 'Insert Into Bildtabelle(Thumbnail, FolderID) Values (:LThumbMemory, :LFolderID)'; FDQueryMain.SQL.Text := SQLString; FDQueryMain.Params[0].LoadFromStream(LThumbMemory, ftgraphic); FDQueryMain.Params[0].LoadFromStream(LFolderId, ftstring); //<== FDQueryMain.ExecSQL(false); ... Erzeugt wird die Guid so:
Delphi-Quellcode:
Was mache ich falsch?
....
if not FileExists(LPath+'IdentFile.cgf') then begin // ist in dem Ordner kein IdentifikationsFile FolderID := CreateIDFile(LPath); Self.FIDFile := FolderID; /// wird eines angelegt end; function TOpenFileFrame.CreateIDFile(LPath : String): String; var IdFile : TFileStream; ID_GUID: TGUID; UniqueName: String; Len: Longint; begin if CreateGUID(ID_GUID) <> 0 then Result := 'Creating GUID failed!' else begin UniqueName := GUIDToString(ID_GUID); IdFile := TFileStream.Create(LPath,fmCreate); try Len := Length(UniqueName); IdFile.Write(Len, SizeOf(Len)); IdFile.Write(PChar(UniqueName)^, Len); finally IdFile.Free; end; Result := 'IdentFile.cgf'; end; end; Gruss Delbor |
AW: Parameter unter Firedac
LFolderId = IdentFile.cgf ?
Binärdaten in einen String laden?
Delphi-Quellcode:
:roll:
Params[0]
Params[0]
Delphi-Quellcode:
FDQueryMain.Params[1].AsAString := TFile.ReadAllText(LFolderId); // natürlich nur, wenn da wirklich nur "Text" in der Datei ist
|
AW: Parameter unter Firedac
Hi Himitsu
Danke für den Tip! Entsprechend habe ich das wie folgt abgeändert
Delphi-Quellcode:
und
function TFDMySQLDml.BildInsertQuery(LThumbMemory: TMemoryStream; FolderId: string): integer;
var SQLString: string; AUser,APass :string; begin SQLString := 'Insert Into Bildtabelle(Thumbnail, FolderID) Values (:LThumbMemory, :FolderID)'; FDQueryMain.SQL.Text := SQLString; FDQueryMain.Params[0].AsStream := LThumbMemory; FDQueryMain.Params[1].AsString := FolderID; FDQueryMain.ExecSQL(false); ....
Delphi-Quellcode:
Meine letzte Fehlermeldung:
function TOpenFileFrame.CreateIDFile(LPath : String): String;
var IdFile : TFileStream; ID_GUID: TGUID; UniqueName: String; Len: Longint; begin if CreateGUID(ID_GUID) <> 0 then Result := 'Creating GUID failed!' else begin UniqueName := GUIDToString(ID_GUID); IdFile := TFileStream.Create(LPath,fmCreate); try Len := Length(UniqueName); IdFile.Write(Len, SizeOf(Len)); IdFile.Write(PChar(UniqueName)^, Len); finally IdFile.Free; end; Result := UniqueName; end; end; Zitat:
Gruss Delbor |
AW: Parameter unter Firedac
hmmmmmmmmm :gruebel:
Etwas in dieser Richtung geht auch nicht?
Delphi-Quellcode:
FDQueryMain.SQL.Text := 'SELECT Thumbnail, FolderID FROM Bildtabelle WHERE 0'; // LIMIT 0
FDQueryMain.Open; FDQueryMain.Insert; FDQueryMain.FieldByName('Thumbnail').AsStream := LThumbMemory; FDQueryMain.FieldByName('FolderID').AsString := FolderID; FDQueryMain.Post; |
AW: Parameter unter Firedac
Hi Himitsu
Ich bin überzeugt, dass es mit der SQL-Syntax nichts zu tun hat. Es hat ja nicht nur unter DBExpress, sondern auch unter FireDac funktioniert, bis ich der Tabelle das zusätzliche Feld verpasst habe. Beim letzten Versuch habe ich mal ein Showmessage eingebaut. Das Resultat: [Window Title] Zitat:
Gruss Delbor |
AW: Parameter unter Firedac
Wenn da 4 bei raus kommt, dann ist irgendwas "kaputt".
TField.Size = bei VARCHAR(MaxLength) sollte MaxLength raus kommen TField.DataSize = bei VARCHAR(MaxLength) als WideStringField sollte 2+MaxLength*2 raus kommen |
AW: Parameter unter Firedac
Zitat:
Du schreibst da einen GUID-String in eine Datei ... aber wozu? Um diesen String als Stream zu haben? Nicht wirklich, oder etwa doch? :gruebel: |
AW: Parameter unter Firedac
Hi zusammen
@Sir Rufo Zitat:
![]() Gleichzeitig soll der vergebene GUID in der DB gespeichert werden. Allerdings ist mir ein Designfehler unterlaufen. Ich habe das Feld für den GUID der Bildtabelle verpasst, aber eigentlich gehört das Ding in die Kategorientabelle - die enthält "Kategorien" (diesen Namen habe ich seinerzeit falsch gewählt), die jedoch eigentlich den Ordnernamen auf der Festplatte entsprechen. Diese Ordner enthalten meist Fotos, die bei einem bestimmten Ereignis entstanden sind, können aber auch solche enthalten, die sich auf mehrere Ereignisse beziehen. @Himitsu: Zitat:
Delphi-Quellcode:
Da ich die Bytes wissen wollte, habe ich Size verwendet. Wobei mir das Leerzeichen nach Size erst jetzt auffällt...
Showmessage('Size of UniqueNameUniqueName := ' + IntToStr(SizeOf(UniqueName)));
Gruss Delbor PS: Dacht ichs doch: Wenn ich SizeOf durch Length ersetze, siehts ganzanders us: [Window Title] Zitat:
|
AW: Parameter unter Firedac
Hi zusammen
Im Moment siehts ganz danach aus, als ob die DB den String/Stream akzeptiert:
Delphi-Quellcode:
Für einmal die komplette Prozedure, welche die Inserts startet. Die Änderungen sind fett dargestellt.
procedure TOpenFileFrame.Btn_OkClick(Sender: TObject);
var AUser,APass, Bildpfad, LPath : String; FolderID : TStringstream; LIdFolder: String; // <=Da Fettdarstellung innerhalb der Delphi-Tags nicht funktioniert - die Änderungen LPathCount, i: integer; begin LPathCount := Self.FPathlist.Count; CM_First.CreateProgressbarDlg(LPathCount); // Create den ProgressbarDialog und zeigt ihn an // Dazu braucht das System etwas Zeit try CM_First.ProgressbarDlg.Top := 20; CM_First.ProgressbarDlg.Left := (CM_First.ProgressbarDlg.Monitor.Width - CM_First.ProgressbarDlg.Width) div 2; Application.ProcessMessages; FDMySQLDml.Pathlist.AddStrings(FPathlist); CM_First.Listbox1.Items.AddStrings(FPathlist); Bildpfad := FPathList[0]; LPath := ExtractFilePath(Bildpfad)+'IdentFile.cgf'; if not FileExists(LPath+'IdentFile.cgf') then begin // ist in dem Ordner kein IdentifikationsFile FolderID := TStringstream.Create; LIdFolder := CreateIDFile(LPath); FolderID.WriteString(LIdFolder); /// wird eines angelegt end; if FDMySQLDml.DefineContentmasterConnection then begin try FDMySQLDml.FDConnectionMySql.StartTransaction; FDMySQLDml.BildTabelleInsert2(100, FolderID); // Startet die Insert-Prozeduren FDMySQLDml.FDConnectionMySql.Commit; except FDMySQLDml.FDConnectionMySql.Rollback; end; end; finally CM_First.ProgressbarDlg.FormStyle := fsnormal; CM_First.ProgressbarDlg.Close; FreeAndNil(CM_First.ProgressbarDlg); if assigned(FolderID) then FolderID.Free; end; end;
Delphi-Quellcode:
In der 2. Prozedur wird die Iteration durch die Pfadliste begonnen, wobei beim 2. Durchlauf eine AV ausgelöst wird, wenn LThumbMemory geleert werden soll. Wie aber ersichtlich ist, wiird LThumbMemory erst nach getaner Arbeit freigegeben.
procedure TFDMySQLDml.BildTabelleInsert2(Seitenlaenge: Integer; FolderID: TStringstream);
var BMap: TBitmap; BJpeg: TJPEGImage; SQLString,Bildname, Bildpfad: String; BildTabelleLastId,IDBild, i,inserted : Integer; LPicture : TPicture; LThumbMemory : TMemoryStream; begin LThumbMemory := TMemoryStream.Create; LPicture := TPicture.Create; BMap := TBitmap.Create; //Lokal BJpeg := TJpegImage.Create; //Lokal BJpeg.CompressionQuality := 100; BJpeg.PixelFormat := jf24Bit; try FTotal := FPathList.Count; for i := 0 to FPathList.Count - 1 do begin FRest := FPathList.Count - i; if FDQueryMain.Active then FDQueryMain.Active := False; Bildname := ExtractFileName(FPathList[i]); Bildpfad := FPathList[i]; Delete(BildName,Length(BildName)-3,4); LThumbMemory.Clear; //<= Beim 2. durchlauf gibts hier eine AV if ExtractFileExt(FPathList[i]) = '.NEF' then begin LPicture.LoadFromFile(FPathList[i]); BMap.Assign(LPicture.Graphic); FModifyBitmap.ScaleBitmaps(BMap, Seitenlaenge); BJpeg.Assign(BMap); BJpeg.SaveToStream(LThumbMemory); BildTabelleLastId := BildInsertQuery(LThumbMemory, FolderId); FReportList.Add(' '+ IntToStr(i)+'-TPicAdmin.BildTabelleInsert2'); FReportList.Add(' '); BildDescribeTabelleInsert(BildTabelleLastId,BildName,Bildpfad); //Ab hier werden nacheinander die Insert-Prozeduren inserted := 1; //aufgerufen if Assigned(FOnInsertedRecord) then //<== Hier wird das Event gefeuert; zu dem Zeitpunkt wurde FOnInsertedRecord(Self,inserted); //<== ein Datensatz über die verschiedenen Tabellen eingefügt end; end; finally LThumbMemory.Free; FreeAndNil(BJpeg); FreeAndNil(BMap); FreeAndNil(LPicture); end; end; Da ich LThumbMemory als Parameter übergebe, kamm mir die Idee, Firedac gäbe den Stream nach getaner Arbeit frei. Das aber kannnicht sein, da ein Probelauf schonmal funktioniert hatte. Gruss Delbor |
AW: Parameter unter Firedac
Ersichtlich ist da gar nichts, denn wir können nicht sehen, was in
Delphi-Quellcode:
mit dem Stream passiert.
BildInsertQuery
BTW
|
AW: Parameter unter Firedac
Hi Sir Rufo
Zitat:
Delphi-Quellcode:
Wie gesagt: Im ersten Durchlauf scheint der Stream FolderId akzeptiert zu werden - ExecSQL läuft scheinbar(?) problemlos ab.
function TFDMySQLDml.BildInsertQuery(LThumbMemory: TMemoryStream; FolderId: TStringstream): integer;
var SQLString: string; begin SQLString := 'Insert Into Bildtabelle(Thumbnail, FolderID) Values (:LThumbMemory, :FolderID)'; FDQueryMain.SQL.Text := SQLString; FDQueryMain.Params[0].AsStream := LThumbMemory; FDQueryMain.Params[1].AsStream := FolderId; FDQueryMain.ExecSQL(false); if FDQueryMain.Active then FDQueryMain.Close; SQLString := 'Select Last_Insert_ID()AS LastID'; FDQueryMain.SQL.Text := SQLString; FDQueryMain.Open; if not FDQueryMain.IsEmpty then result := FDQueryMain.FieldByName('LastID').AsInteger; // end; Soll dann im zweiten Durchlauf LThumbmemory neu befüllt werden, muss es erstmal geleert werden. Ich könnte wohl auch die Position zurücksetzen, dass hätte aber zur Folge, dass Reste des vorigen Bildes angezeigt werden, wenn das aktuelle Bild kleiner ist. Zitat:
Zitat:
Embarcadero äussert sich nicht darüber (oder ich habs gründlich überlesen), wie ein GUID binär gespeichert werden kann. Einzig TPictur ist eventuell überflüssig; bei der Erstellung der Procedur schien es mir aber der einfachste weg zu sein, ein Bild zu laden. Das wäre allenfalls zu optimieren... Gruss Delbor PS:
Delphi-Quellcode:
Das lädt erstmal ein NEF-Bild. Und davon brauche ich eine Bitmap und ein Jpeg. Nef-Bilder könnten auch mit WICImage geladen werden, aber das hab ich wieder verworfen. Soweit ich mmich erinnere, sind die WicImage-Bilder nicht mehr im Original vorhanden, wenn sie erstmal, in was auch immer, umgewamdelt wurden.
LPicture.LoadFromFile(FPathList[i]);
|
AW: Parameter unter Firedac
Siehe englische Hilfeseite zu
![]()
Delphi-Quellcode:
TFDParam.AsStream
Zitat:
Zumal ein
Delphi-Quellcode:
das auch erledigt. Also ist der Stream schonmal komplett überflüssig.
FDQueryMain.Params[0].Assign( MyImage );
Eine GUID ist auch nur eine Bytefolge und kann mit ![]()
Delphi-Quellcode:
ganz gemütlich in ein ByteArray geschoben werden.
System.Sysutils.TGUIDHelper
|
AW: Parameter unter Firedac
Hi SirRufo
Zitat:
![]() Zitat:
Wenn ich eine Bitmap erstelle und diese bearbeite, will ich sie so, wie ich sie bearbeitet habe, in der DB. Ansonsten müsste ich ein Bild jedesmal neu als Bitmap erstellen und neu bearbeiten, wenn Bedarf besteht. Gruss Delbor |
AW: Parameter unter Firedac
Statt Grafik in Stream und Stream an Parameter einfach nur Grafik per Assign an den Parameter.
|
AW: Parameter unter Firedac
Hi Sir Rufo
Erstmal danke für den Tip: Zitat:
Gruss Delbor |
AW: Parameter unter Firedac
Das funktioniert mit allen Klassen, die von
Delphi-Quellcode:
abgeleitet sind und
TPersistent
Delphi-Quellcode:
implementieren.
IStreamPersist
Und
Delphi-Quellcode:
erfüllt dieses Kriterium - siehe:
TGraphic
![]() Korrektur:
Delphi-Quellcode:
wird beim Assign gesondert behandelt und nicht über
TStrings
Delphi-Quellcode:
IStreamPersist
|
AW: Parameter unter Firedac
Hi zusammen
In Bezug auf den GUID tut sich noch ein Problemm auf. Um mich selbst zu zitieren: Zitat:
Und das wiederum widerspricht eigentlich den Normalisierungsregeln: Ich hab jetzt nur mal testweise Bilder aus einem Ordner in die DB aufgenommen - 444 Stück, und jedem wird der selbe GUID zugeordnet. Wie liesse sich das lösen? Gruss Delbor |
AW: Parameter unter Firedac
Was entspricht nicht der Normalisierung? Die GUID an dem Bild zu speichern?
Wie kommst du da drauf? Den eindeutigen Pfad zu der Bilddatei bekommst du doch nur über die GUID des Ordners und dem relativen Pfad zu der Datei. Als gehören diese Informationen auch zu dem Datensatz. |
AW: Parameter unter Firedac
Hi Sir Rufo
Zum einen schreien 444 Datensaetze mit einem Feld, das überall den gleichen Wert hat, nach einer eigenen Tabelle. Eine Adresstabelle, enthält ja in der Regel aauch eine eigene Strassentabelle, in der jede Strasse einmal aufgeführt ist, aber mit beliebig vielen Personen verknüpft ist. Dabei gibts hier noch die Besonderheit, dass in vielen Orten je eine =Post- und eine Bahnhofstrasse vorhanden ist. Genau genomen müssten solche Strassen (auch Marktstrasse uund -Gasse etc) nur gerade in einer Strassentabelle vorhanden sein, könnten aber mit beliebigen Personen und fast beliebigen Orten verknüpft werden. Klar, diese 200KB sind nicht viel und das schreit von daher seinerseits nach Brechen der Normalisierung - was ja je nach dem auch mal sinnvoll sein kann. Zitat:
Ich hab in den letzten Tagen mal ein kleines Beispielprogramm mit TClientdataset nachgebaut, einfach, um zu sehen, was dabei wirklich raussschaut. Der Nachteil ist, dass die Fotos im Explorer nicht mehr als solche erkennbar sind. Der Vorteil wohl, dass sie gerade dadurch wohl etwas besser vor versehentlichem löschen geschützt sind. Gruss Delbor |
AW: Parameter unter Firedac
Die GUID ist doch als Schlüssel gedacht, von daher kann sie natürlich beliebig oft vorkommen. Wozu also noch eine weitere Tabelle?
|
AW: Parameter unter Firedac
Hi zusammen
Zitat:
Gruss Delbor |
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:11 Uhr. |
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