AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Datenbanken Delphi DB Abfrage als JSON ausgeben
Thema durchsuchen
Ansicht
Themen-Optionen

DB Abfrage als JSON ausgeben

Ein Thema von Whookie · begonnen am 29. Feb 2024 · letzter Beitrag vom 1. Mär 2024
Antwort Antwort
Whookie

Registriert seit: 3. Mai 2006
Ort: Graz
445 Beiträge
 
Delphi 10.3 Rio
 
#1

DB Abfrage als JSON ausgeben

  Alt 29. Feb 2024, 17:26
Datenbank: dbExpress • Version: ? • Zugriff über: sqlite
Hallo zusammen,
ich habe aktuell eine sqlite-DB mit der ich über dbExpress zugreife die DB enthält unter anderem zwei TEXT Felder im Format '[1,2,3,4,5...300]' mit 80 bis 2000 Werten. Diese Felder (und andere) hole ich mir über eine entsprechende TSQLQuery und wandle das ganze nach JSON (vereinfacht):

Delphi-Quellcode:
    LQueryObject := TJSONObject.Create;
    LQArray := TJSONArray.Create;
    LQueryObject.AddPair('data', LQArray);
    fQuery.CommandText := '.....';

    fQuery.Open;
    fQuery.First;
    while Not fQuery.Eof do
    begin
      LItem := TJSONObject.Create;
      for i := 0 to fLongVSQuery.Fields.Count-1 do
      begin
        if Not fQuery.Fields[i].IsNull then
        begin
          LItem.AddPair(
            fQuery.FieldDefs[i].Name,
            fQuery.Fields[i].AsString
          )
        end;
      end;

      LQArray.AddElement(LItem);
      fQuery.Next;
    end;
    fQuery.Close;

    Result := LQueryObject.ToString;
    ...

Alle "anderen" Felder meiner Abfrage sind Strings und können wie oben übernommen werden. Für die TEXT Felder funktioniert das nicht, denn ich bekomme (natürlich) als Ergebnis:

Code:
{
  "data": [
    {
      "...": "...."
      "myarray": "[1,2,3,4,5..,300]"      statt: "myarray": [1,2,3,4,5,..,300]
    {
      ...
    }
  ]
}
Daher habe ich für diese Felder eine "Sonderbehandlung" implementiert:

Delphi-Quellcode:
  LItem.AddPair(
    fQuery.fFieldDefs[i].Name,
    TJSONObject.ParseJSONValue(fQuery.Fields[i].AsString) As TJSONArray;
  )

Das ergibt zwar sauberen JSON-Output, ist aber leider extrem spürbar bei der Abfragedauer (bei ~ 1000 zurückgegebenen Objekten).

Daher die alles entscheidende Frage:

Ist es irgendwie möglich, den schon vorhandenen String zu verwenden ohne ihn zuerst zurück in ein TJSON-Integer-Array und dann wieder in einen String zu wandeln?

Ich habe das ganz auch mit einer TStringList umgesetzt (also JSON selber erzeugen), dass ist viel schneller aber auch deutlich weniger schön/flexibel, ist das eine vernünftige Lösung?
Whookie

Software isn't released ... it is allowed to escape!
  Mit Zitat antworten Zitat
Neumann

Registriert seit: 6. Feb 2006
Ort: Moers
536 Beiträge
 
Delphi 12 Athens
 
#2

AW: DB Abfrage als JSON ausgeben

  Alt 1. Mär 2024, 11:53
Was ist wenn man die strings einfach quoted "1,2,..300"
Ralf
Gruß vom Niederrhein
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.475 Beiträge
 
Delphi 12 Athens
 
#3

AW: DB Abfrage als JSON ausgeben

  Alt 1. Mär 2024, 12:58
Was ist wenn man die strings einfach quoted "1,2,..300"
Das Problem ist hier der Aufruf von AddPair, dessen zweiter Parameter eben ein String ist (wegen AsString), wo es doch eigentlich ein Array sein sollte. Die Umwandlung dieses Strings mittels ParseJSONValue erfüllt ja auch ihren Zweck - ist halt nur spürbar langsamer. Immerhin werden da eine ziemliche Anzahl von JsonValues erzeugt, die am Ende ja wieder in den JSON-Ergebnisstring umgewandelt werden.

Ein Ausweg wäre ein manuelles Schreiben des JSON-Strings.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#4

AW: DB Abfrage als JSON ausgeben

  Alt 1. Mär 2024, 13:02
Jupp, AsString ist nunmal ein String, also wird es als String gespeichert.
Du mußt das also zerlegen und dann daraus ein JSON-Array machen.

Du kannst manuell diese Integer-Liste zerlegen und ein JsonArray bauen, oder (mit den [ ] drumrum) es vom JsonParser in ein Array konvertieren lassen
und das Array dann einfügen.


Wenn/da die JSON-Implementation vom Delphi jetzt nicht sooo flott ist,
bleibt nur der Ausweg unschön den JSON-Text selbst zusammenzubauen
oder eine andere JSON-Lib zu suchen.
$2B or not $2B

Geändert von himitsu ( 1. Mär 2024 um 13:07 Uhr)
  Mit Zitat antworten Zitat
Whookie

Registriert seit: 3. Mai 2006
Ort: Graz
445 Beiträge
 
Delphi 10.3 Rio
 
#5

AW: DB Abfrage als JSON ausgeben

  Alt 1. Mär 2024, 14:55
Danke für die Hinweise! Beim Überlegen bin ich dann auf folgende Möglichkeit gekommen:

Delphi-Quellcode:
type
  TJSONStringedArray = class(TJSONString)
  public
    procedure ToChars(Builder: TStringBuilder); override;
  end;

implementation

{ TJSONStringArray }

procedure TJSONStringedArray.ToChars(Builder: TStringBuilder);
begin
// inherited;
  if Not IsNULL then
  begin
    Builder.Append(Value);
  end;
end;
Hinzufügen, kann ich mein Array dann wie folgt:

Delphi-Quellcode:
  ...
    LItem.AddPair(
      AQuery.fJSONDefs[i].Name,
      TJSONStringedArray.Create(fQuery.Fields[i].AsString)
    )
Damit stimmt dann auch die Ausgabe im JSON.

Anm.: Man könnte noch ToBytes() überschreiben um die Ausgabe in einen Stream zu ermöglichen (verwende ich aber nicht).
Whookie

Software isn't released ... it is allowed to escape!
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:49 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