it-swarm.com.de

Verhindern der ungültigen Eingabesyntax für den Typ json in Postgres

Ich habe eine Textspalte, die JSON enthält und auch Plan-Text. Ich möchte es in JSON konvertieren und dann eine bestimmte Eigenschaft auswählen. Beispielsweise:

user_data
_________
{"user": {"name": "jim"}}
{"user": {"name": "sally"}}
some random data string

Ich habe es versucht:

select user_data::json#>'{user,name}' from users

Ich bekomme:

ERROR:  invalid input syntax for type json
DETAIL:  Token "some" is invalid.
CONTEXT:  JSON user_data, line 1: some...

Kann man das verhindern?

11

Wenn Sie die Zeilen mit ungültigem JSON überspringen möchten, müssen Sie zuerst test prüfen, ob der Text gültiges JSON ist. Sie können dies tun, indem Sie eine Funktion erstellen, die versucht, den Wert zu analysieren und die Ausnahme für ungültige JSON-Werte abzufangen.

CREATE OR REPLACE FUNCTION is_json(input_text varchar) RETURNS boolean AS $$
  DECLARE
    maybe_json json;
  BEGIN
    BEGIN
      maybe_json := input_text;
    EXCEPTION WHEN others THEN
      RETURN FALSE;
    END;

    RETURN TRUE;
  END;
$$ LANGUAGE plpgsql IMMUTABLE;

Wenn Sie das haben, könnten Sie die is_json Funktion in einer CASE oder WHERE Klausel, um die gültigen Werte einzugrenzen.

-- this can eliminate invalid values
SELECT user_data::json #> '{user,name}'
FROM users WHERE is_json(user_data);

-- or this if you want to fill will NULLs
SELECT
  CASE
    WHEN is_json(user_data)
      THEN user_data::json #> '{user,name}'
    ELSE
      NULL
  END
FROM users;
5
Andy Carlson

Verwenden Sie diese Funktion:

create or replace function is_json(text)
returns boolean language plpgsql immutable as $$
begin
    perform $1::json;
    return true;
exception
    when invalid_text_representation then 
        return false;
end $$;

Prüfung:

with users(user_data) as (
values
    ('{"user": {"name": "jim"}}'),
    ('not json'),
    ('{"user": {"name": "sally"}}'),
    ('also not json')
)

select user_data::json#>'{user,name}' as name
from users
where is_json(user_data);

  name   
---------
 "jim"
 "sally"
(2 rows)
7
klin