I have a text column that contains JSON and also plan text. I want to convert it to JSON, and then select a particular property. For example:
user_data _________ {"user": {"name": "jim"}} {"user": {"name": "sally"}} some random data string
I've tried:
select user_data::json#>'{user,name}' from users
I get:
ERROR: invalid input syntax for type json DETAIL: Token "some" is invalid. CONTEXT: JSON user_data, line 1: some...
Is it possible to prevent this?
PostgreSQL offers two types for storing JSON data: json and jsonb . To implement efficient query mechanisms for these data types, PostgreSQL also provides the jsonpath data type described in Section 8.14. 7. The json and jsonb data types accept almost identical sets of values as input.
PostgreSQL allows you to work on both JSON and SQL data to implement relational and non-relational queries. This way, PostgreSQL allows you to leverage SQL commands for processing data stored in tables of respective database servers.
You can save any valid json value to either json or to a jsonb column. But you cannot bind it as string/ text / varchar , if you use prepared statements (use casts instead in sql, like UPDATE ... SET json_col = $1::json or bind it as unknown ).
Another data type in PostgreSQL is JSON, which stands for JavaScript Object Notation. It is an open-standard format that contains key-value pairs. The main objective of using the JSON data type is to transfer data between a server and a web application. JSON is human-readable text distinct from the other formats.
If you want to skip the rows with invalid JSON, you must first test if the text is valid JSON. You can do this by creating a function which will attempt to parse the value, and catch the exception for invalid JSON values.
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;
When you have that, you could use the is_json
function in a CASE
or WHERE
clause to narrow down the valid values.
-- 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;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With