4

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?

1 Answer 1

8

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;
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.