How to update an empty jsonb column using jsonb_set in postgresql? - postgresql

My purpose is to update a jsonb column using jsonb_set, which is currently null, with an object having more than one key-value pairs. The update command executes successfully but it is not updating anything, the column is still coming up empty. I am trying the following query.
UPDATE tab
set value = jsonb_set(value, '{}', '{"a" : 100, "b" : [100, 200]}'::jsonb)
where id = 100;
Any solutions ?

From what I've understood, it appears you don't need jsonb_set for this case. Simply cast the string to jsonb for updating
UPDATE tab
set value = '{"a" : 100, "b" : [100, 200]}'::jsonb
where id = 100
--and value is null; --additional check if you need.
Demo

Related

What does `target` mean in `jsonb_set` of postgresql?

I am using jsonb type in a column in postgresql11. And I'd like to update one field in the json data and I see there is a function jsonb_set which can be used. (https://www.postgresql.org/docs/current/functions-json.html).
However, based on the document,
jsonb_set ( target jsonb, path text[], new_value jsonb [, create_if_missing boolean ] ) → jsonb
Returns target with the item designated by path replaced by new_value, or with new_value added
if create_if_missing is true (which is the default) and the item designated by path does not
exist. All earlier steps in the path must exist, or the target is returned unchanged. As with
the path oriented operators, negative integers that appear in the path count from the end of
JSON arrays. If the last path step is an array index that is out of range, and create_if_missing
is true, the new value is added at the beginning of the array if the index is negative, or at
the end of the array if it is positive.
The first argument is target. What does target mean here? Do I need to do a query to get existing value and put it as target?
I have tried below update statement:
my current data is:
# select "taxes" from "Sites" where "id" = '6daa9b5d-d5b2-4b0d-a8ee-5ad2cb141594';
taxes
--------------------------------------------------------------------------------------------------------------
{"feePercent": 0, "percent": 0}
And I tried below update:
# update "Sites" set "feePercent" = jsonb_set('{"feePercent": 0, "percent": 0}', '{feePercent}', 1) where "siteUuid"='6daa9b5d-d5b2-4b0d-a8ee-5ad2cb141594';
but I got below error:
ERROR: function jsonb_set(unknown, unknown, integer) does not exist
LINE 1: update "Sites" set "feePercent" = jsonb_set('{"feePerce...
jsonb_set() modifies a specific JSON object. So, your target is the JSON object (or JSON column) which you want to modify.
jsonb_set(my_jsonb_to_be_modified, ...)
So, if you had this JSON object;
{"my":"old", "json":"object"}
With the function you can turn it into:
{"my":"new", "json":"object"}
The code is:
demo:db<>fiddle
SELECT jsonb_set('{"my":"old", "json":"object"}', '{my}', '"new"')
The target is the original JSON object, the path points to the element you want to modify, and new_value is the new value for the element you specified in the path.
In that case my had the value old, which turns into new now.
From PostgreSQL v14 on, you can use subscripts to make this UPDATE statement look natural:
UPDATE "Sites"
SET taxes['feePercent'] = to_jsonb(1)
WHERE id = '6daa9b5d-d5b2-4b0d-a8ee-5ad2cb141594';
For earlier versions, you will have to use jsonb_set like this:
UPDATE "Sites"
SET taxes = jsonb_set(taxes, ARRAY['feePercent'], to_jsonb(1))
WHERE id = '6daa9b5d-d5b2-4b0d-a8ee-5ad2cb141594';
The effect is the same: the whole JSON is read, a new JSON is created and stored in a new version of the row.
All this becomes much simpler if you don't use JSON, but regular table columns.

Updating JSONB object using another table

I am trying to update a JSONB field in one table with data from another table. For example,
update ms
set data = data || '{"COMMERCIAL": 3.4, "PCT" : medi_percent}'
from mix
where mix.id = mss.data_id
and data_id = 6000
and set_id = 20
This is giving me the following error -
Invalid input syntax for type json
DETAIL: Token "medi_percent" is invalid.
When I change medi_percent to a number, I don't get this error.
{"COMMERCIAL": 3.4, "PCT" : medi_percent} is not a valid JSON text. Notice there is no string interpolation happening here. You might be looking for
json_build_object('COMMERCIAL', 3.4, 'PCT', medi_percent)
instead where medi_percent is now an expression (that will presumably refer to your mix column).

How to insert new parameter into column in PostgreSql

I have a table called device, the table has a column called devicMeta. The deviceMeta looks like
{"id":"1234567890", "firmware":"1.001","hardware":"1.0"}
I want to insert a new parameter into column 'deviceMeta', for example "company":'ABC', the expected result is
{"id":"1234567890","firmware":"1.001","hardware":"1.0","company":'ABC'}
How can I do this using PostgreSql's UPDATE command
UPDATE "device"
?
WHERE "id" = '1234567890'
Assuming that column is defined as jsonb (which it should be) you can simply concatenate the new key/value pair:
update device
set devicemeta = devicemeta || '{"company": "ABC"}'
where id = 123456789;

PostgreSQL - Set JSONB property from column value

I have a numeric column total_price and I want to move it to a jsonb property named price_detail. For example, if the total_price value is 1000, the expected price_detail value is {"totalPrice": 1000}
I've tried using jsonb_set but the result is empty object {}
UPDATE public.orders SET price_detail =
jsonb_set('{}'
, '{}'
, jsonb_build_object('totalPrice', total_price::numeric))
If I set the path,
UPDATE public.orders SET price_detail =
jsonb_set('{}'
, '{totalPrice}'
, jsonb_build_object('totalPrice', total_price::numeric))
The result is {"totalPrice":{"totalPrice":1000}} which is unexpected
How can I set the totalPrice property correctly?
You don't need the JSONB_SET, just use JSONB_BUILD_OBJECT:
UPDATE orders
SET price_detail = JSONB_BUILD_OBJECT('totalPrice', total_price::numeric)
Demo on dbfiddle

Postgres 9.6 update jsonb column to add new attribute with a value from query

I have a table xyz, with a metadata jsonb column in postgres.
Table : xyz
column : metadata, type = jsonb
metadata = {"exceptions": {"first_exception": "first_value"} }
I want to add a new sub_attribute
desired metadata = {"exceptions": {"first_exception": "123"},{"second_exception": "234"} }
I can use the
update xyz
SET metadata = jsonb_set(metadata->'exceptions', '{second_exception}', '"234"', true).
But I want to get the value 234 from a select query. I am not able to figure how to combine the select query with the update to do this.
You can do
UPDATE xyz
SET metadata = jsonb_set(metadata, '{exceptions, second_exception}', other.value::jsonb)
FROM other
WHERE other.column = xyz.column
Pay attention that {"exceptions": {"first_exception": "123"},{"second_exception": "234"}} is not a valid json and update will give you following result {"exceptions": {"first_exception": "123", "second_exception": "234"}}