I have a work_item table that has the following schema
+---------+----------+---------------+
| id | data | data_type |
+------------------------------------+
| | | |
| | | |
| | | |
+---------+--------------------------+
and a document_type table with the following schema:
+---------+----------+
| id | name |
+--------------------+
| | |
| | |
| | |
+---------+-----------
The data column is a json column that has a Type field. This is a sample column data:
{"Id":"5d35a41f-3e91-4eda-819d-0f2d7c2ba55e","WorkItem":"24efa9ea-4291-4b0a-9623-e6122201fe4a","Type":"Tax Document","Date":"4/16/2009"}
I need to update data columns whose data_type
column value is DocumentModel and Type field values matches a value in the name column of the document_type table to a json object containing the document_type id and the document_type name. Something like this {"id": "<doc_type_id>", name: "<doc_type_name>"}
.
I tried to do this by executing this query:
UPDATE wf.work_item wi
SET data = jsonb_set(data::jsonb, '{Type}', (
SELECT jsonb_build_object('id', dt.id, 'name', dt.name)
FROM wf.document_type AS dt
WHERE wi.data ->> 'Type'::text = dt.name::text
), false)
WHERE wi.data_type = 'DocumentModel';
The above script runs without an error. However, what it does is something unwanted, it changes the data and data_type columns to null instead of updating the data column.
What is the issue with my script? Or can you suggest a better alternative to do a the desired update?
The problem arises when the document type is missing from the document_type
table. Then jsonb_set()
returns null
(as the subquery does not give any results). A safer solution is to use the from
clause in update
:
update wf.work_item wi
set data = jsonb_set(
data::jsonb,
'{Type}',
jsonb_build_object('id', dt.id, 'name', dt.name),
false)
from wf.document_type as dt
where wi.data_type = 'DocumentModel'
and wi.data ->> 'Type'::text = dt.name::text;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With