Home > OS >  How do I update data inside a stringified JSON object in SQL?
How do I update data inside a stringified JSON object in SQL?

Time:01-16

So I have three databases - an Oracle one, SQL Server one, and a Postgres one. I have a table that has two columns: name, and value, both are texts. The value is a stringified JSON object. I need to update the nested value.

This is what I currently have:

name: 'MobilePlatform', 
value:
    '{
       "iosSupported":true,
       "androidSupported":false,
    }'

I want to add {"enableTwoFactorAuth": false} into it.

CodePudding user response:

In PostgreSQL you should be able to do this:

UPDATE mytable
SET MobilePlatform = jsonb_set(MobilePlatform::jsonb, '{MobilePlatform,enableTwoFactorAuth}', 'false');

CodePudding user response:

In Postgres, the plain concatenation operator || for jsonb could do it:

UPDATE mytable
SET    value = value::jsonb || '{"enableTwoFactorAuth":false}'::jsonb
WHERE  name  = 'MobilePlatform';

If a top-level key "enableTwoFactorAuth" already exists, it is replaced. So it's an "upsert" really.

Or use jsonb_set() for manipulating nested values.

The cast back to text works implicitly as assignment cast. (Results in standard format; any insignificant whitespace is removed effectively.)

If the content is valid JSON, the storage type should be json to begin with. In Postges, jsonb would be preferable as it's easier to manipulate, but that's not directly portable to the other two RDBMS mentioned.

(Or, possibly, a normalized design without JSON altogether.)

CodePudding user response:

For ORACLE 21

update mytable
set json_col = json_transform(
    json_col,
    INSERT '$.value.enableTwoFactorAuth' = 'false'
)
where json_exists(json_col, '$?(@.name == "MobilePlatform")')
;

With json_col being JSON or VARCHAR2|CLOB column with IS JSON constraint.

(but must be JSON if you want a multivalue index on json_value.name:

create multivalue index ix_json_col_name on mytable t ( t.json_col.name.string() );

)

CodePudding user response:

Two of the databases you are using support JSON data type, so it doesn't make sense to have them as stringified JSON object in a Text column.

Oracle: https://docs.oracle.com/en/database/oracle/oracle-database/21/adjsn/json-in-oracle-database.html

PostgreSQL: https://www.postgresql.org/docs/current/datatype-json.html

Apart from these, MSSQL Server also provides methods to work with JSON data type.

MS SQL Server: https://learn.microsoft.com/en-us/sql/relational-databases/json/json-data-sql-server?view=sql-server-ver16

Using a JSON type column in any of the above databases would enable you to use their JSON functions to perform the tasks that you are looking for.

If you've to use Text only then you can use replace to add the key-value pair at the end of your JSON

update dataTable set value = REPLACE(value, '}',",\"enableTwoFactorAuth\": false}") where name = 'MobilePlatform'

Here dataTable is the name of table.

The cleaner and less riskier way would be connect to db using the application and use JSON methods such as JSON.parse in Javascript and JSON.loads in Python. This would give you the JSON object (dictionary in case of Python) to work on. You can look for similar methods in other languages as well.

But i would suggest, if possible use JSON columns instead of Text to store the JSON value wherever possible.

  • Related