Postgres: Comment convertir une chaîne json en texte?

93

La valeur Json peut être constituée d'une valeur de chaîne. par exemple.:

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

Comment puis-je extraire cette chaîne en tant que valeur de texte postgres?

::TEXTne fonctionne pas. Il renvoie json cité, pas la chaîne d'origine:

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

Merci.

PS J'utilise PostgreSQL 9.3

e79ene
la source
stackoverflow.com/q/19414361/562459 peut vous aider. Peut-être pas.
Mike Sherrill 'Cat Recall'
Problème similaire avec un tableau de chaînes, stackoverflow.com/q/45243186/287948
Peter Krauss

Réponses:

58

Il n'y a aucun moyen dans PostgreSQL de déconstruire un objet JSON scalaire. Ainsi, comme vous le faites remarquer,

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

est 15,

L'astuce consiste à convertir le JSON en un tableau d'un élément JSON, puis à extraire cet élément en utilisant ->>.

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

retournera 11.

Robert M. Lefkowitz
la source
8
C'est dommage qu'on json_extract_path_text()ne puisse pas référencer l'élément racine (AFAIK).
Erwin Brandstetter
3
Fait intéressant, il y avait une discussion de remue - méninges apparemment de retour à l'étape de la conception de l' API en 2012 dans lequel une fonction from_jsonse est proposé, mais non mis en œuvre wiki.postgresql.org/wiki/JSON_API_Brainstorm
nikola
147

En 9.4.4, l'utilisation de l' #>>opérateur fonctionne pour moi:

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

À utiliser avec une colonne de table:

select jsoncol #>> '{}' from mytable;
Ian Timothy
la source
2
Semble être la solution la plus simple dans Postgres 9.4. Cependant ne fonctionne pas pour la version 9.3.
e79ene
2
@hasen L'OP indique qu'il essaie d'extraire du texte d'une valeur JSON et to_json(...)est simplement un moyen simple de créer une valeur JSON à utiliser comme exemple dans une instruction courte d'une ligne. Vous le remplaceriez certainement par le nom d'une colonne JSON si vous interrogiez une table comme vous le décrivez. De plus, pour dissiper un point de confusion potentiel, votre distribution (...)::textest redondante car l' #>>opérateur renvoie du texte par définition (et c'est la raison pour laquelle l'opérateur a été utilisé en premier lieu). Vous pouvez conserver les parenthèses mais supprimer la distribution ::text.
Ian Timothy
1
Quelqu'un pourrait-il expliquer ce que fait #>>et '{}'fait? Je ne peux pas tout à fait suivre cela et aucun de ces termes n'est compatible avec Google. Cette réponse a résolu mon problème, je veux juste savoir pourquoi.
valadil
1
@valadil La documentation de l' #>>opérateur est ici .
Ian Timothy
1
@valadil Dans ce cas, il existe un objet JSON de niveau supérieur ou racine text. Cela peut ressembler à une chaîne, mais c'est un objet JSON. Pour convertir cet objet de JSON en texte, utilisez l' #>>opérateur. Mais cet opérateur a besoin de vous pour spécifier un chemin. Le chemin vers cet objet racine est {}. Donc SELECT '"test"'::jsonb #>> '{}'signifie "obtenir l'objet à la racine du chemin et le convertir en texte".
Ian Timothy
3

M. Curious était également curieux à ce sujet. En plus de l' #>> '{}'opérateur, dans 9.6+ on peut obtenir la valeur d'une chaîne jsonb avec l' ->>opérateur:

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

Si l'on a une valeur json, alors la solution consiste à convertir d'abord en jsonb:

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

Une manière simple de faire ceci:

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

Convertissez simplement la chaîne json en une liste json

Zhemin Zhou
la source
0

- >> fonctionne pour moi.

version postgres:

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

Requete:

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

Production:

  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
la source
Merci de l'avoir signalé, j'ai corrigé la version ci
Surinder le
La question originale est de savoir comment obtenir la valeur d'une chaîne JSON sous forme de texte avec (pas de clé d'objet). Cette réponse est juste la différence entre ->et ->>lors de l'utilisation d'une clé. Voir cette réponse ou cette réponse .
Ian Timothy