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

e79ene
quelle
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.

Robert M. Lefkowitz
quelle
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;
Ian Timothy
quelle
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)
Mr. Curious
quelle
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
Surinder
quelle
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

Zhemin Zhou
quelle