I am using Go and "github.com/jackc/pgx/v4/pgxpool"
.
One of the fields in my table has json
and I need to update two keys in one query.
The first problem was to update several keys at once but I think it works fine now with a nested jsonb_set
.
A bigger problem is how parameter substitution works in this case.
UPDATE my_table
SET
first_column=$2,
json_column = JSONB_SET(JSONB_SET(
json_column::jsonb,
'{first_key_name}',
$3,
true),
'{second_key_name}',
$4,
true),
updated_at = now() at time zone 'utc'
WHERE id=$1
This yields, however, the invalid input syntax for type json
error. Adding either to_jsonb()
or ::jsonb
around/after the parameters ($3, $4) didn't help.
Below is how the pgx
library is used to pass the arguments to the query. Both key value are of string
type.
err := pool.QueryRow(ctx, myQuery,
id,
first_column,
first_key_value,
second_key_value
).
Scan(...)
After some experimenting, it seems that one way to make it work is to use jsonb_build_array
and then get the 0-th item. That looks totally unreadable and I am almost sure there must be a simpler way to achieve this.
UPDATE my_table
SET
first_column=$2,
json_column = JSONB_SET(JSONB_SET(
json_column::jsonb,
'{first_key_name}',
jsonb_array_element(jsonb_build_array($3::text), 0),
true),
'{second_key_name}',
jsonb_array_element(jsonb_build_array($4::text), 0),
true),
updated_at = now() at time zone 'utc'
WHERE id=$1
You could use ||
operator here. Initially lets say the record look like this:
{"a":"b","key2":"value2"}
After update
update dummy set j=j::jsonb||'{"a": "new_value"}
{"a":"new_value","key2":"value2"}
Remember it replaces top level keys if found otherwise create a new key. use jsonb_build_object to create json object on right side of ||operator
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.