Postgres: Wie konvertiere ich einen JSON-String in Text?


87

Der Json-Wert kann aus einem Zeichenfolgenwert bestehen. z.B.:

postgres=# SELECT to_json('Some "text"'::TEXT);
     to_json
-----------------
 "Some \"text\""

Wie kann ich diese Zeichenfolge als Postgres-Textwert extrahieren?

::TEXTfunktioniert nicht Es wird json in Anführungszeichen zurückgegeben, nicht die ursprüngliche Zeichenfolge:

postgres=# SELECT to_json('Some "text"'::TEXT)::TEXT;
     to_json
-----------------
 "Some \"text\""

Vielen Dank.

PS Ich benutze PostgreSQL 9.3


stackoverflow.com/q/19414361/562459 könnte helfen. Möglicherweise nicht.
Mike Sherrill 'Cat Recall'

Ähnliches Problem mit Array von Strings, stackoverflow.com/q/45243186/287948
Peter Krauss

Antworten:


53

In PostgreSQL gibt es keine Möglichkeit, ein skalares JSON-Objekt zu dekonstruieren. Wie Sie hervorheben,

select  length(to_json('Some "text"'::TEXT) ::TEXT);

ist 15,

Der Trick besteht darin, den JSON in ein Array aus einem JSON-Element zu konvertieren und dieses Element dann mit zu extrahieren ->>.

select length( array_to_json(array[to_json('Some "text"'::TEXT)])->>0 );

wird 11 zurückgeben.


8
Schade, dass json_extract_path_text()das Root-Element (AFAIK) nicht referenziert werden kann.
Erwin Brandstetter

3
Interessanterweise gab es 2012 bereits in der API-Entwurfsphase eine Brainstorming-Diskussion, in der eine Funktion from_jsonvorgeschlagen, aber nicht implementiert wurde. wiki.postgresql.org/wiki/JSON_API_Brainstorm
nikola

138

In 9.4.4 funktioniert die Verwendung des #>>Operators für mich:

select to_json('test'::text) #>> '{}';

So verwenden Sie eine Tabellenspalte:

select jsoncol #>> '{}' from mytable;

2
Scheint die einfachste Lösung in Postgres 9.4 zu sein. Funktioniert jedoch nicht für 9.3.
E79ene

2
@hasen Das OP gibt an, dass er versucht, Text aus einem JSON-Wert zu extrahieren, und dies to_json(...)ist einfach eine einfache Möglichkeit, einen JSON-Wert zu erstellen, mit dem als Beispiel in einer kurzen einzeiligen Anweisung gearbeitet werden kann. Sicherlich würden Sie es durch den Namen einer JSON-Spalte ersetzen, wenn Sie eine Tabelle wie beschrieben abfragen würden. Um einen Punkt möglicher Verwirrung zu beseitigen, ist Ihre Besetzung (...)::textüberflüssig, da der #>>Operator per Definition Text zurückgibt (und der Grund dafür ist, den Operator überhaupt zu verwenden). Sie könnten die Klammern behalten, aber die Besetzung fallen lassen ::text.
Ian Timothy

1
Könnte jemand was buchstabieren #>>und '{}'tun? Ich kann dem nicht ganz folgen und keiner der Begriffe ist Google-freundlich. Diese Antwort hat mein Problem behoben, ich möchte nur wissen warum.
Valadil

1
@valadil Die Dokumentation für den #>>Bediener finden Sie hier .
Ian Timothy

1
@valadil In diesem Fall gibt es ein JSON-Objekt der obersten Ebene oder des Stamms text. Es mag wie eine Zeichenfolge aussehen, ist aber ein JSON-Objekt. Verwenden Sie den #>>Operator, um dieses Objekt von JSON in Text zu konvertieren . Für diesen Operator müssen Sie jedoch einen Pfad angeben. Der Pfad zu diesem Stammobjekt lautet {}. Bedeutet SELECT '"test"'::jsonb #>> '{}'also "Holen Sie sich das Objekt in den Stammpfad und konvertieren Sie es in Text".
Ian Timothy

3

Mr. Curious war auch neugierig darauf. Zusätzlich zum #>> '{}'Operator kann man in 9.6+ mit dem ->>Operator den Wert einer jsonb-Zeichenfolge abrufen :

select to_jsonb('Some "text"'::TEXT)->>0;
  ?column?
-------------
 Some "text"
(1 row)

Wenn man einen json-Wert hat, besteht die Lösung darin, zuerst in jsonb umzuwandeln:

select to_json('Some "text"'::TEXT)::jsonb->>0;
  ?column?
-------------
 Some "text"
(1 row)

1

- >> arbeitet für mich.

postgres version:

<postgres.version>11.6</postgres.version>

Abfrage:

select object_details->'valuationDate' as asofJson, object_details->>'valuationDate' as asofText from MyJsonbTable;

Ausgabe:

  asofJson       asofText
"2020-06-26"    2020-06-26
"2020-06-25"    2020-06-25
"2020-06-25"    2020-06-25
"2020-06-25"    2020-06-25

Vielen Dank für den Hinweis, ich habe die obige Version korrigiert
Surinder

0

Ein einfacher Weg, dies zu tun:

SELECT  ('[' || to_json('Some "text"'::TEXT) || ']')::json ->> 0;

Konvertieren Sie einfach den JSON-String in eine JSON-Liste

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.