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 № 1Ich 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:
- 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
Zweiter Ansatz, verwenden
FDMemTable.SaveToStream
; Das gleiche funktioniert fürFDMemTable.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
- 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
- Vergessen Sie bei Verwendung von FdMemTable nicht, die TFDStanStorageJSONLink-Komponente für das Datenmodul zu ziehen
- 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.
- 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;