Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   TIdBytes in Datenbankfeld speichern (https://www.delphipraxis.net/211179-tidbytes-datenbankfeld-speichern.html)

hawiwo 9. Aug 2022 09:24

Datenbank: Firebird • Version: 4.0.1 • Zugriff über: FireDAC

TIdBytes in Datenbankfeld speichern
 
Hallo,
ich habe einen TIdUDPServer und möchte die empfangenen Daten in eine Firebird Datenbank möglichst ohne viel
Umwandlung bzw. Umwandlungsfehler speichern.

Zum Test habe ich eine Tabelle mit dem Feld:
DATA BINARY(260) Nullable
angelegt

mit
void __fastcall TForm1::IdUDPServer1UDPRead(TIdUDPListenerThread *AThread, const TIdBytes AData, TIdSocketHandle *ABinding)

FDQuery1->Params->CreateParam(ftBytes, "param1", ptInput);
FDQuery1->ParamByName("param1")->AsVarByteStr = ??AData??
...
FDQuery1->SQL->Text = "INSERT INTO MYTAB(DATA) VALUES (:param1)";
FDQuery1->ExecSQL();

Wie bekomme ich die TIdBytes AData in ein Datenbankfeld?
Hat jemand sowas schon mal gemacht? Wie geht das?

auch wenn das C++ ist...Ein Delphi Beispiel wäre mir schon recht.

Redeemer 9. Aug 2022 18:05

AW: TIdBytes in Datenbankfeld speichern
 
Du versuchst hier ein array of Byte einer AnsiString-Eigenschaft zuzuweisen. Das klappt natürlich nicht und sollte auch in dem Fehler stehen.
Dass TFDParam offensichtlich auch keine BLOBs sondern nur CLOBs unterstützt (selbst AsBlob repräsentiert ein CLOB), ist auch sehr seltsam. Könnte daran liegen, dass man der Länge von TBytes oft nicht vertrauen kann (sie sind meist ein Vielfaches von 4 Kibi groß) und daher eine separate Längenangabe zu Rate ziehen müsste.

Ohne Ahnung von Firebird zu haben:
Konvertiere deinen BLOB (TIdBytes) in einen "CLOB" (RawByteString) oder schreibe ihn in einen TMemoryStream (ggf. einen Erben) und weise ihn AsStream zu (dadurch besitzt TFDParam den Stream).

Ich bin mir übrigens nicht sicher, ob deine Methode eventuell öfter aufgerufen wird, als du denkst/möchtest.

himitsu 10. Aug 2022 00:07

AW: TIdBytes in Datenbankfeld speichern
 
ftBytes oder nicht doch ftBlob?

Rufe doch einfach mal über ein SELECT dieses Feld ab und schau, welchen TField-ClassType und FieldType/DataType das Field hat.



TIdBytes ist sowas wie ein TBytes, bzw. TArray<Byte>

und das könntest du in einen RawByteString (oder AnsiString) kopieren
oder in einen Stream kopieren
oder in ein Variant-Array kopieren
oder als Pointer übergeben.



Bis vor einer Weile war ein dynamisches Array noch bis zu 2GB-2*4B-1 groß ... inzwischen aber bis 8 Exabyte - 16 Byte - 1 (wenn 64 Bit).
Ein String/AnsiString ist aber weiterhin nur bis maximal 2GB-3*4B (und -4*4B wenn 64Bit) groß ... früher waren mal String und DynArray intern halbwegs kompatibel, aber das hat man seit Win64 kaputt gemacht, weil man NUR die DynArrays erweitert hat.


LoadFromStream / SaveToStream = als Stream
GetBlobRawData / SetBlobRawData = als Byte-Block, bzw. Pointer (PByte)

AsVarByteStrs[] / AsByteStrs[] = als mehrere AnsiString

AsVarByteStr / AsByteStr = als EIN AnsiString (aber ich würde stattdessen besser einen RawByteString nutzen)

AsBytes[] = jedes Byte einzeln

AsVariant = dürfte wohl als Variant-Array sein -> VarArrayCreate/VarArrayHighBound/VarArrayLock oder DynArrayToVariant/DynArrayFromVariant usw.



k.A. was der Unterschied zwischen AsVarByte*** und AsByte*** sein soll.


Alle Zeitangaben in WEZ +1. Es ist jetzt 09:36 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