Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   JSONArray in Insert-Statement (https://www.delphipraxis.net/207661-jsonarray-insert-statement.html)

Ykcim 20. Apr 2021 15:49

Datenbank: MySQL • Version: 8 • Zugriff über: FireDac

JSONArray in Insert-Statement
 
Hallo Zusammen,

ich bin gerade an einer Client / Server App. Der Client schickt ein JSArray-String an den Server. Der Server soll diese Daten in eine MySQL-Tabelle schreiben. Ich habe gelesen, dass ich den JSON-String direkt dazu benutzen könne. Stimmt das?

Ich habe es so versucht, wie ich es verstanden hatte, aber ohne Erfolg...

Delphi-Quellcode:
INSERT INTO versand (bnumber, print_status, ship_date, ship_time, tnumber, vdienstl)
VALUES (
'[{"bnumber":"200026","print_status":"print_ok","ship_date":"2021.04.16","ship_time":"12:42:22","tnumber":"00346527107258","vdienstl":"(Standard-Versand)"}]'
)
Bei diesem Versuch bekomme ich die Fehlermeldung:

Column count doesn't match value count at Row 1

Kennt jemand diese Vorgehensweise oder kann mir jemand einen anderen Weg weisen, wie ich aus diesem String die Daten in eine MySQL-Tabelle bekomme?

Vielen Dank
Patrick

jaenicke 20. Apr 2021 16:31

AW: JSONArray in Insert-Statement
 
Du musst einfach die Feldliste weglassen. ;-)
Die steht ja schließlich im JSON Text drin.

Code:
INSERT INTO versand VALUES (
'{"bnumber":"200026","print_status":"print_ok","ship_date":"2021.04.16","ship_time":"12:42:22","tnumber":"00346527107258","vdienstl":"(Standard-Versand)"}'
)

Ykcim 20. Apr 2021 16:45

AW: JSONArray in Insert-Statement
 
Das wäre ja super, wenn das geht. Ich hatte bis heute noch nie etwas von der Möglichkeit gehört.

Ich habe es jetzt so versucht:
Delphi-Quellcode:
INSERT INTO versand VALUES (
'{   
   "bnumber":"200026",
   "print_status":"print_ok",
   "ship_date":"2021.04.16",
   "ship_time":"12:42:22",
   "tnumber":"003465271258",
   "vdienstl":"(Standard-Versand)"
   }'
)

Aber leider bekomme ich dennoch die Fehlermeldung:
Column count doesn't match value count at row 1


Ich habe es sorgfältig geprüft, dass die Felder alle da sind und das die Schreibweisen identisch sind.
Ich sehe auch keine verfänglichen Schreibweisen in dem String. Hast Du noch eine Idee, was ich falsch machen könnte?

Vielen Dank
Patrick

jaenicke 20. Apr 2021 16:51

AW: JSONArray in Insert-Statement
 
Haben die Felder denn auch den Typ json?

// EDIT:
Und ich habe gerade gelesen, dass es nur mit InnoDB als Speichersystem geht. Ob das so ist und noch stimmt, weiß ich nicht.

Ykcim 20. Apr 2021 17:00

AW: JSONArray in Insert-Statement
 
Die Engine ist InnoDB

Aber die Felder sind VARCHAR, Date und Time Felder...
Ich habe auch mal eben eine Test-Tabelle angelegt, in der ich alle Datenfelder als JSON definiert habe, aber da bekomme ich die gleiche Fehlermeldung...

Wie lösen andere das Thema. Ich wäre auch bereit, mit einem klassischen insert zu arbeiten, bekomme aber die Werte nicht aus dem JS_Array. In dem Beispiel ist es nur eine Zeile, es können aber beliebig viele sein...

LG Patrick

jaenicke 20. Apr 2021 17:50

AW: JSONArray in Insert-Statement
 
Zitat:

Zitat von Ykcim (Beitrag 1487470)
Wie lösen andere das Thema. Ich wäre auch bereit, mit einem klassischen insert zu arbeiten, bekomme aber die Werte nicht aus dem JS_Array. In dem Beispiel ist es nur eine Zeile, es können aber beliebig viele sein...

Es gibt fertige ORMs, die solche Mappings automatisch machen können.

Ansonsten findest du in der Unit System.JSON einiges um auf die Json-Objekte und -Arrays zuzugreifen, wenn du bei Bordmitteln bleiben möchtest.

Neumann 20. Apr 2021 19:50

AW: JSONArray in Insert-Statement
 
Ich finde Superobject ganz praktisch, um JSON Arrays/Objekte zu verarbeiten.

Leicht verständlich und schnell erlernbar.

KodeZwerg 20. Apr 2021 21:04

AW: JSONArray in Insert-Statement
 
mORMot hat auch was nettes an bord für solche zwecke (_Json).
Bedienung ist kinderleicht solange der JSON inhalt fest vorgeschrieben ist (feldnamen oder wie man das nennt).
Delphi-Quellcode:
var
  Ykcim: Variant;
begin
  Ykcim := _Json(JSON_String);
  Writeln(Ykcim.bnumber); // 200026
  Writeln(Ykcim.print_status); // print_ok
  Writeln(Ykcim.ship_date); // 2021.04.16
  Writeln(Ykcim.ship_time); // 12:42:22
  Writeln(Ykcim.tnumber); // 003465271258
  Writeln(Ykcim.vdienstl); // (Standard-Versand)
end.

jobo 21. Apr 2021 13:37

AW: JSONArray in Insert-Statement
 
mysql ist nicht so toll im Umgang mit json wie z.B. postgres, aber etwas kann es auch.
Vielleicht hilft Dir 'json_extract'
Code:
SELECT
  JSON_EXTRACT('{"Name": "Bart", "Age": 10}', '$.Name') AS 'Result';
https://database.guide/json_extract-...ment-in-mysql/

Es gibt noch einige weitere Funktionen für den Umgang mit Arrays und Array Aggregation.
Wenn Dein json komplexter ist, muss der (oder die) "path" Parameter (hier $.name) entsprechend aufgebaut werden.

Ykcim 21. Apr 2021 21:24

AW: JSONArray in Insert-Statement
 
Hallo Zusammen,

ich habe die verschiedenen Vorschläge versucht umzusetzen und habe in diese Richtungen gelesen, was ich gefunden habe, aber bin irgendwie nicht zurande gekommen. Jetzt habe ich gerade noch einmal gesucht und ein Code gefunden, den ich umbauen konnte, mit dem es funktioniert...

Delphi-Quellcode:
type
  TRows = array of array of string;
  TCols = array of string;



procedure TForm1.AdvGlowButton1Click(Sender: TObject);
var  JS_Array: TJSONArray;
      JS_Value: TJSONValue;
      Insert_String, Value_String: string;
      I, J: integer;
      Rows: TRows;
      Cols: TCols;
begin
   SetLength(Cols, 6);
   SetLength(Rows, Length(Cols),0);
   Cols[0] := 'BNumber';
   Cols[1] := 'Print_Status';
   Cols[2] := 'Ship_Date';
   Cols[3] := 'Ship_Time';
   Cols[4] := 'TNumber';
   Cols[5] := 'VDienstL';
   JS_Array := TJSONArray.Create;
   try
      JS_Array := TJSONObject.ParseJSONValue(JS_ArrayString) as TJSONArray;
      I := 0;
      for JS_Value in JS_Array do begin
         SetLength(Rows, Length(Cols), Length(Rows[0])+1);
         for J := 0 to Length(Cols) -1 do begin
            Rows[J,I] := JS_Value.GetValue<string>(Cols[J]);
         end;
         INC(I);
      end;

      for I := 0 to Length(Rows[0]) -1 do begin
         if I=0 then begin
            Value_String := '';
         end
         else begin
            Value_String := Value_String + ', ';
         end;
         Value_String := Value_String+ '(';
         for J := 0 to Length(Cols) -1 do begin
            if J=0 then begin
               Value_String := Value_String + QuotedStr(Rows[J,I]);
            end
            else begin
               Value_String := Value_String + ', ' + QuotedStr(Rows[J,I]);
            end;
         end;
      end;
      Insert_String := 'INSERT INTO versand (bnumber, print_status, ship_date, ship_time, tnumber, vdienstl) '+
                       'VALUES '+Value_String;
   finally
      JS_Array.Free;
   end;
Vielen Dank für die Unterstützung!

Guten Nacht
Patrick


Alle Zeitangaben in WEZ +1. Es ist jetzt 05:05 Uhr.
Seite 1 von 2  1 2      

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