Datenbankeintrag aufsplitten

hevapeyma

Benutzer
Beiträge
23
Hallo an alle Teilnehmer



Ich habe ein Problem mit einem ungünstigen Datenbankeintrag. Der Eintrag ist ein Ergebnis eines Java-Programms. Der Eintrag sieht wie folgt aus:



{"rightAnswers":2,"totalAnswers":5,"time":"1m 29s"}



Ich habe nun in die Tabelle die Spalten right_Answers, total_Answers und Time eingefügt. Nun möchte ich die Werte in die entsprechenden Felder kopieren, d. h. die 2 in die Spalte „right_Answers“, die 5 in die Spalte „total_Answers“ und die Zeit in Spalte „Time“, mit der Besonderheit, dass die Zeit nur in Sekunden als int gespeichert wird, als hier wären es 89 Sekunden. Die Einträge sollen mittels SQL-Code kopiert werden.

Vielen Dank für die Hilfe!

Grüße,

Thomas
 
Werbung:
Nun denn. Der String ist ein JSON-Objekt, ich verwende PostgreSQL und das kann JSON ;-)

Code:
test=*# \d hevapeyma
               Table "public.hevapeyma"
  Column  |   Type   | Collation | Nullable | Default
----------+----------+-----------+----------+---------
 value    | jsonb    |           |          |
 ra       | integer  |           |          |
 ta       | integer  |           |          |
 duration | interval |           |          |

test=*# select * from hevapeyma ;
                          value                           | ra | ta | duration
----------------------------------------------------------+----+----+----------
 {"time": "1m 29s", "rightAnswers": 2, "totalAnswers": 5} |    |    |
(1 row)

test=*# update hevapeyma set duration = (rtrim(split_part(value->>'time',' ', 1),'m')::int * 60 + rtrim(split_part(value->>'time',' ', 2),'s')::int) * '1second'::interval, ra = (value->>'rightAnswers')::int, ta=(value->>'totalAnswers')::int;
UPDATE 1
test=*# select * from hevapeyma ;
                          value                           | ra | ta | duration
----------------------------------------------------------+----+----+----------
 {"time": "1m 29s", "rightAnswers": 2, "totalAnswers": 5} |  2 |  5 | 00:01:29
(1 row)

test=*#

Man muß halt den String mit der Zeitangabe zerlegen und passend rechnen und in die korrekten Datentypen konvertieren, aber ansonsten eher trivial.
 
Ach ja: falls Du duration als Integer in Sekunde haben willst:

Code:
test=*# select rtrim(split_part(value->>'time',' ', 1),'m')::int * 60 + rtrim(split_part(value->>'time',' ', 2),'s')::int from hevapeyma ;
 ?column?
----------
       89
(1 row)

Das Update also entsprechend ändern.
 
Werbung:
Oder ganz old school zu Fuß:
Code:
DECLARE   @i VARCHAR(100) = '{"rightAnswers":2,"totalAnswers":5,"time":"1m 29s"}'
SELECT   left(right(@i,datalength(@i)-patindex('%"rightAnswers":%',@i)-14),charindex(',',right(@i,datalength(@i)-patindex('%"rightAnswers":%',@i)-14))-1) AS right_Answers,
       left(right(@i,datalength(@i)-patindex('%"totalAnswers":%',@i)-14),charindex(',',right(@i,datalength(@i)-patindex('%"totalAnswers":%',@i)-14))-1) AS total_Answers,
       convert(TIME,'00:' + replace(replace(left(right(@i,datalength(@i)-patindex('%"time":%',@i)-7),charindex('"',right(@i,datalength(@i)-patindex('%"time":%',@i)-7))-1),'m ',':'),'s','')) AS [time]
Die Konvertierung der Zeit ist natürlich maximal ätzend und Fehleranfällig (wenn z.B. plötzlich Stunden dazu kommen). Das dürfte aber auch bei JSON Support gegeben sein. Vielleicht schreibt man sich dafür lieber eine eigene Funktion.
 
Zurück
Oben