I need to update a specific value in a column with the json type.
All solutions I found online are either for jsonb or don’t seem quite right and give me an syntax error and I don’t know why.
That we are on the same page: it’s a Postgres 15.3 database that was created like this:
create table if not exists "DOCF000T6"."assignments"
(
id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
correlation_id VARCHAR ( 31 ) UNIQUE NOT NULL,
reference_id VARCHAR ( 100 ),
jdata json NOT NULL,
errormassage VARCHAR
);
And the one json that needs to be edited:
{
"directoryRefId": "00DhDRC53dkoMUsC73znji4UoDUz",
"useragent": "agent-ftps",
"creationdate": "2023-12-12 15:41:03.3",
"data": {
"variables": {
"dms-dokument-name": "Notifiation 22.09.2022.pdf",
"dms-vo-remind": "false",
"dms-messagebox": "E_BN",
"dms-file-number": "0000-15840",
"dms-pio-oe": "MUB",
}
}
}
I need to update the dms-file-number like this
UPDATE assignments
SET jdata['data']['variables']['dms-file-number'] = '0001-05840'
WHERE
jdata-> 'data' -> 'variables' ->> 'dms-file-number' = '0000-15840';
I know that something like that should work for jsonb, but I can’t get it to work.
2
Answers
Zegarek'S anser workex perfectly i just trew out the jsonb_pretty because i realy don't need it in my case and i added a WHERE to not completely wipe my Database
As discussed in the comments, you can cast to
::jsonb
, usejsonb_set()
, then cast back to::json
. A side effect of that will be removed insignificant whitespace, reordered and deduplicated keys. You can restore formatting by running the value throughjsonb_pretty()
on its way back: demo at db<>fiddleSome display configurations might line-wrap
jsonb_pretty()
fiedjdata
in the table below. The fiddle should preserve the real resulting format."data": {
"variables": {
"dms-pio-oe": "MUB",
"dms-vo-remind": "false",
"dms-messagebox": "E_BN",
"dms-file-number": "0777-7",
"dms-dokument-name": "Notifiation 22.09.2022.pdf"
}
},
"useragent": "agent-ftps",
"creationdate": "2023-12-12 15:41:03.3",
"directoryRefId": "00DhDRC53dkoMUsC73znji4UoDUz"
}
You could also consider if it’s maybe worth to
alter
the column permanently and leave it asjsonb
, which will make it lighter, faster and conveniently indexable, adding lots of flexibility through support of additional operators and functions, at the expense of having to cascade this change to where the value’s used in your code. Also some minor behavioral changes, like inability to hold duplicate keys, preserve custom formatting and custom key order.If formatting and whitespace were your primary concern, you’ll be disappointed with the solution using pure
json
withoutjsonb
: it can preserve custom key order and duplicate keys but exploding, then re-aggregating the object still wipes the whitespace. Here I added areplace()
to add some newlines for readability:"useragent" : "agent-ftps",
"creationdate" : "2023-12-12 15:41:03.3",
"data" : {"variables" : { "dms-dokument-name" : "Notifiation 22.09.2022.pdf",
"dms-vo-remind" : "false",
"dms-messagebox" : "E_BN",
"dms-file-number" : "0777-7",
"dms-pio-oe" : "MUB" }} }
As you can see, it’s not pretty and as you can guess, it’s pretty slow compared to
jsonb
. To make things worse, you should actually add a middle level to make sure you don’t lose additional entries neighbouringvariables
underdata
– this now assumes there will only ever bevariables
as the only key underdata
and if there’s anything else, this would discard that.