Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Postgresql : Is there a way to select all valid json data type

I have a table :

table

---------------------
id  | value
---------------------
1   | invalid_json
---------------------
2   | valid_json
---------------------
3   | invalid_json
---------------------

First of all, value is in varchar type not really declared as json, and it has some reasons why it is set up like that. Anyway, my question is about the possibility, and if possible how. Is it possible to create an sql to find only the rows that contains a VALID json formatted data even though the column data type is var char?

A sort of :

"select * from table where (condition that data is a valid json)";
like image 627
muffin Avatar asked Oct 21 '14 15:10

muffin


People also ask

How do I query JSON data type in PostgreSQL?

Querying the JSON documentPostgreSQL has two native operators -> and ->> to query JSON documents. The first operator -> returns a JSON object, while the operator ->> returns text. These operators work on both JSON as well as JSONB columns. There are additional operators available for JSONB columns.

How do I select all data in PostgreSQL?

If you want to select data from all the columns of the table, you can use an asterisk ( * ) shorthand instead of specifying all the column names. The select list may also contain expressions or literal values. Second, specify the name of the table from which you want to query data after the FROM keyword.

How do I query JSON data?

To query JSON data, you can use standard T-SQL. If you must create a query or report on JSON data, you can easily convert JSON data to rows and columns by calling the OPENJSON rowset function. For more information, see Convert JSON Data to Rows and Columns with OPENJSON (SQL Server).


2 Answers

As a_horse_with_no_name stated, you can write a function trying to cast to json and return a result based on the success of that operation.

CREATE FUNCTION is_json(varchar) RETURNS boolean AS $$
  DECLARE
    x json;
  BEGIN
    BEGIN
      x := $1;
    EXCEPTION WHEN others THEN
      RETURN FALSE;
    END;

    RETURN TRUE;
  END;
$$ LANGUAGE plpgsql IMMUTABLE;

Making it IMMUTABLE will make it operate quickly for repeated strings (such as an empty string for example), but it highly depends on the size of your table.

Then you can query your data.

SELECT * FROM table WHERE is_json(value);

If the table is big and you are about to repeat that query a lot of times, I would add an additional is_json boolean field to the table. Then create a trigger/rule to check the validity upon INSERT/UPDATE on that table.

However, having mixed data types in the same column is not a good idea, mind changing your data structure in case you are considering such a scenario.

like image 105
Kouber Saparev Avatar answered Sep 20 '22 21:09

Kouber Saparev


I recently solved a similar problem by doing a simple check on the string for curly braces:

WHERE value LIKE '{%}'

This of course depends on the data you expect, and will not match all valid JSON nor exclude all non-JSON. In my case I had a field that used to take a simple character string (still present in old records) but now takes a JSON object wrapped in curly braces. If your case is like mine--you know some specifics about what the valid and invalid data look like--you might do it this way.

like image 24
workerjoe Avatar answered Sep 19 '22 21:09

workerjoe