/ / Delphi FDQuery an Json - Json, Delphi, Delphi-Xe, Delphi-10.1-Berlin, Firedac

Delphi FDQuery an Json - Json, Delphi, Delphi-Xe, Delphi-10.1-Berlin, Firedac

Ich versuche, das Ergebnis meiner Sqlite-Abfrage in einen Json umzuwandeln. um die gleichen Verfahren zu verwenden, die ich mit Remote-Bindung an SQL Server von PHP verwenden.

Der Code funktioniert, aber denken Sie, dass es eine bessere Lösung ist?

Macht da jemand das?

function TLogin.RetornaRegistros(query:String): String;
var
FDQuery : TFDQuery;
field_name,nomeDaColuna,valorDaColuna : String;
I: Integer;
begin
FDQuery := TFDQuery.Create(nil);
try
FDQuery.Connection := FDConnection1;
FDQuery.SQL.Text := query;
FDQuery.Active := True;
FDQuery.First;

result := "[";
while (not FDQuery.EOF) do
begin

result := result+"{";
for I := 0 to FDQuery.FieldDefs.Count-1 do
begin
nomeDaColuna  := FDQuery.FieldDefs[I].Name;
valorDaColuna := FDQuery.FieldByName(nomeDaColuna).AsString;
result := result+"""+nomeDaColuna+"":""+valorDaColuna+"",";
end;
Delete(result, Length(Result), 1);
result := result+"},";

FDQuery.Next;
end;
FDQuery.Refresh;

Delete(result, Length(Result), 1);
result := result+"]";

finally
FDQuery.Free;
end;
end;

Antworten:

2 für die Antwort № 1

Ich habe gerade meine erste Antwort unten geändert, um verschiedene Feldtypen zu kombinieren, um Nummer, Datum und Booleschen Wert in das entsprechende JSON-Format zu konvertieren. Ich kommentiere die Typen, die ich nicht getestet habe. Aussehen

Verwendet {...} System.JSON;

Var
FDQuery : TFDQuery;
field_name,Collumnname,CollumnValue : String;
I: Integer;

LJSONObject:TJsonObject;
begin
FDQuery := TFDQuery.Create(nil);
try
FDQuery.Connection := FDConnection1;
FDQuery.SQL.Text := query;
FDQuery.Active := True;
FdQuery.BeginBatch;//Don"t update external references until EndBatch;
FDQuery.First;
LJSONObject:= TJSONObject.Create;
while (not FDQuery.EOF) do
begin
for I := 0 to FDQuery.FieldDefs.Count-1 do
begin
CollumnName  := FDQuery.FieldDefs[I].Name;

              Case FDQuery.FieldDefs[I].Datatype of
ftBoolean:
IF FDQuery.FieldDefs[I].Value=True then   LJSONObject.AddPair(TJSONPair.Create(TJSONString.Create( CollumnName),TJSONTrue.Create)) else
LJSONObject.AddPair(TJSONPair.Create(TJSONString.Create( CollumnName),TJSONFalse.Create));
ftInteger,ftFloat{,ftSmallint,ftWord,ftCurrency} :
LJSONObject.AddPair(TJSONPair.Create(TJSONString.Create( CollumnName),TJSONNumber.Create(FDQuery.FieldDefs[I].value)));
ftDate,ftDatetime,ftTime:
LJSONObject.AddPair(TJSONPair.Create(TJSONString.Create( CollumnName),TJSONString.Create(FDQuery.FieldDefs[I].AsString)));
//or TJSONString.Create(formatDateTime("dd/mm/yyyy",FDQuery.FieldDefs[I].Value));
else LJSONObject.AddPair(TJSONPair.Create(TJSONString.Create( CollumnName),TJSONString.Create(FDQuery.FieldDefs[I].AsString)));
End;

            FDQuery.Next;
end;
FdQuery.EndBatch;
finally
FDQuery.Free;
Showmessage(LJSonObject.ToString);
end;
end;

Weitere Informationen zu Dataset.DataType http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/delphivclwin32/DB_TFieldType.html

Weitere Informationen zu JSONTypes https://community.embarcadero.com/blogs/entry/json-types-for-server-methods-in-datasnap-2010-4


1 für die Antwort № 2

Das ist kein guter Ansatz. Ich schlage wirklich vor, zumindest Baumoptionen in Betracht zu ziehen:

  1. Verwenden Sie die Leistung der System.JSON-Einheit.

Verwendet {...} System.JSON;

Var
FDQuery : TFDQuery;
field_name,Collumnname,CollumnValue : String;
I: Integer;

LJSONObject:TJsonObject;
begin
FDQuery := TFDQuery.Create(nil);
try
FDQuery.Connection := FDConnection1;
FDQuery.SQL.Text := query;
FDQuery.Active := True;
FdQuery.BeginBatch;//Don"t update external references until EndBatch;
FDQuery.First;
LJSONObject:= TJSONObject.Create;
while (not FDQuery.EOF) do
begin
for I := 0 to FDQuery.FieldDefs.Count-1 do
begin
CollumnName  := FDQuery.FieldDefs[I].Name;
CollumnValue := FDQuery.FieldByName(CollumnName).AsString;
LJSONObject.AddPair(TJSONPair.Create(TJSONString.Create( CollumnName),TJSONString.Create(CollumnValue)));
FDQuery.Next;
end;
//FDQuery.Refresh; that"s wrong
FdQuery.EndBatch;
finally
FDQuery.Free;
Showmessage(LJSonObject.ToString);
end;
end;

https://www.youtube.com/watch?v=MLoeLpII9IE&t=715s

  1. Zweiter Ansatz, verwenden FDMemTable.SaveToStream; Das gleiche funktioniert für FDMemTable.SaveToFile; Legen Sie eine TFDMemTable auf das Datamodule (oder auch auf das Formular).

    fMStream:TMemoryStream;
    Begin
    FDQuery := TFDQuery.Create(nil);
    try
    FDQuery.Connection := FDConnection1;
    FDQuery.SQL.Text := query;
    FDQuery.Active := True;
    //fdMemTable1.Data:=fdQuery.Data; {note *2}
    fdMemTable1.CloneCursor(FdQuery,true,true);{note *3}
    fMStream:=TMemoryStream.Create;
    FdMemTable1.SaveToStream(fMStream,sfJson);
    finally
    FDQuery.Free;
    FdMemTable.Close;
    end;
    

Jetzt können Sie die lesen JSON Inhalt Zum Beispiel folgende Antwort Konvertieren von TMemoryStream in 'String' in Delphi 2009

function MemoryStreamToString(M: TMemoryStream): string;
begin
SetString(Result, PChar(M.Memory), M.Size div SizeOf(Char));
end;

und du hast den json als String

  1. Das BatchMove vorgeschlagen von @VictoriaMarotoSilva

Sie können verwenden BatchMove Komponenten, die eine Schnittstelle zum Verschieben bietetDaten zwischen Datasets, aber es funktioniert besser für die Sicherung und den Import, wenn Sie Daten im Laufwerks-, XML- oder JSON-Format speichern möchten. Ich habe noch keine Beispiele gefunden, die Daten verwenden, die sich im Speicher bewegen. Wenn jemand anderes ein Beispiel hat, kommentieren Sie dies bitte.

Anmerkungen

  1. Vergessen Sie bei Verwendung von FdMemTable nicht, die TFDStanStorageJSONLink-Komponente für das Datenmodul zu ziehen
  2. Methode .Data funktioniert nur für FiredacDatasets (Datasets mit dem Präfix FD). Verwenden Sie stattdessen die Methode .Copydata, um Daten für memTable in alten Datensätzen zuzuweisen.
  3. Sorry Leute, ich ändere mich .Data zu .CloneCursor um denselben Speicherplatz mit beiden Datensätzen zu teilen.

0 für die Antwort № 3

Überlegen Sie zu verwenden TFDBatchMove Komponente. Es dient zur direkten Übertragung von Daten zwischen zwei Datenbanken mit zusätzlicher Unterstützung für Zuordnungen. Als Quelle und Ziel kann ein Text, ein Dataset oder eine SQL-Abfrage an eine der von FireDAC unterstützten Datenbank-Engines verwendet werden.


0 für die Antwort № 4

Das Delphi MVC Framework enthält einen leistungsstarken Mapper zum Zuordnen von json zu Objekten und von Datensätzen zu Objekten. Der Mapper ist ein Teilprojekt. Es ist unabhängiger Code, der auch in anderen Projekten verwendet werden kann. Es ist Open Source!

Vorteil ist, dass beispielsweise boolesche Werte in den Typ TJSONBool und nicht in eine Zeichenfolge konvertiert werden. Ich schlage vor, einen Blick auf die Proben zu werfen.

https://github.com/danieleteti/delphimvcframework/tree/master/samples/objectsmapperssamples


0 für die Antwort № 5

Wahrscheinlich nicht die beste Lösung, und Sie können dies so ändern, wie der JSON formatiert werden soll. Hier ist eine kurze Beispiellösung:

function GetDataSetAsJSON(DataSet: TDataSet): TJSONObject;
var
f: TField;
o: TJSOnObject;
a: TJSONArray;
begin
a := TJSONArray.Create;
DataSet.Active := True;
DataSet.First;
while not DataSet.EOF do begin
o := TJSOnObject.Create;
for f in DataSet.Fields do
o.AddPair(f.FieldName, VarToStr(f.Value));
a.AddElement(o);
DataSet.Next;
end;
DataSet.Active := False;
Result := TJSONObject.Create;
Result.AddPair(DataSet.Name, a);
end;