JSONB change params value - sql

I have a table that contains a json type in one row called whole_params, and I would like to change values if json param called exampleParam equals value1 I want to change it to value2
UPDATE table_name t
SET whole_params = json_set(whole_params, '{exampleParam}')::jsonb)
WHERE t.whole_params ->> 'exampleParam' = 'value1';
I wrote something like that but I do not know how to change that 'value1', any ideas?

You just need to use jsonb_set() instead of json_set() with a slight change as
UPDATE table_name t
SET whole_params = jsonb_set(whole_params, '{exampleParam}','"value2"')
WHERE t.whole_params ->> 'exampleParam' = 'value1';

Related

Updating column value to replace a particular character in Teradata

I need help with replacing column value to replace all '%' delimiter with '~'.
Example:
CTP%3A1c5d8384-5980-4bee-88f5-aed7594594ba%7ESV%3ANA%7ECUST%3Anew%7ECSR%3AGREATER+BOSTON+MARKET%7ECSD%3ANORTHEAST+DIVISION%7EZIP%3A02140%7EBFT%3AAll+digital+buyflow%7Cdotcom%7EBPT%3ANA%7EIDV%3ANA%7EMRC%3ANA%7ESIKE%3ANA%7ESIKP%3ANA%7ESIKS%3ANA%7ERAF%3Ano
CTP%3A7ef7b00a-10dc-41e9-8691-0a01463703c9%7ESV%3ANA%7ECUST%3Aexisting%7ECSR%3ABIG+SOUTH+REGION%7ECSD%3ACENTRAL+DIVISION%7EZIP%3A30101%7EBFT%3AAll+digital+buyflow%7Cdotcom%7EBPT%3ANA%7EIDV%3ANA%7EMRC%3ANA%7ESIKE%3ANA%7ESIKP%3ANA%7ESIKS%3ANA%7ERAF%3Ano
CTP%3A9ed9ba57-4227-444a-9385-101bbc0df3bc%7ESV%3ANA%7ECUST%3Anew%7ECSR%3ABIG+SOUTH+REGION%7ECSD%3ACENTRAL+DIVISION%7EZIP%3A30047%7EBFT%3AAll+digital+buyflow%7Cdotcom%7EBPT%3ANA%7EIDV%3ANA%7EMRC%3ANA%7ESIKE%3ANA%7ESIKP%3ANA%7ESIKS%3ANA%7ERAF%3Ano
CTP%3Ae46e7133-340d-41b9-9cdf-2baea14c86b6%7ESV%3ANA%7ECUST%3Aexisting%7ECSR%3ASEATTLE+MARKET%7ECSD%3AWEST+DIVISION%7EZIP%3A98223%7EBFT%3AAddOnChannel%7EBPT%3ANA%7EIDV%3ANA%7EMRC%3ANA%7ESIKE%3ANA%7ESIKP%3ANA%7ESIKS%3ANA%7ERAF%3Ano
Expected Output:
CTP~3A1c5d8384-5980-4bee-88f5-aed7594594ba~7ESV~3ANA~7ECUST~3Anew~7ECSR~3AGREATER+BOSTON+MARKET~7ECSD~3ANORTHEAST+DIVISION~7EZIP~3A02140~7EBFT~3AAll+digital+buyflow~7Cdotcom~7EBPT~3ANA~7EIDV~3ANA~7EMRC~3ANA~7ESIKE~3ANA~7ESIKP~3ANA~7ESIKS~3ANA~7ERAF~3Ano
CTP~3A7ef7b00a-10dc-41e9-8691-0a01463703c9~7ESV~3ANA~7ECUST~3Aexisting~7ECSR~3ABIG+SOUTH+REGION~7ECSD~3ACENTRAL+DIVISION~7EZIP~3A30101~7EBFT~3AAll+digital+buyflow~7Cdotcom~7EBPT~3ANA~7EIDV~3ANA~7EMRC~3ANA~7ESIKE~3ANA~7ESIKP~3ANA~7ESIKS~3ANA~7ERAF~3Ano
CTP~3A9ed9ba57-4227-444a-9385-101bbc0df3bc~7ESV~3ANA~7ECUST~3Anew~7ECSR~3ABIG+SOUTH+REGION~7ECSD~3ACENTRAL+DIVISION~7EZIP~3A30047~7EBFT~3AAll+digital+buyflow~7Cdotcom~7EBPT~3ANA~7EIDV~3ANA~7EMRC~3ANA~7ESIKE~3ANA~7ESIKP~3ANA~7ESIKS~3ANA~7ERAF~3Ano
CTP~3Ae46e7133-340d-41b9-9cdf-2baea14c86b6~7ESV~3ANA~7ECUST~3Aexisting~7ECSR~3ASEATTLE+MARKET~7ECSD~3AWEST+DIVISION~7EZIP~3A98223~7EBFT~3AAddOnChannel~7EBPT~3ANA~7EIDV~3ANA~7EMRC~3ANA~7ESIKE~3ANA~7ESIKP~3ANA~7ESIKS~3ANA~7ERAF~3Ano
I have tried to use OREPLACE but it didn't work.
UPDATE A
SET ORDER_INFO = OREPLACE(ORDER_INFO,'%','~')
WHERE ORDER_INFO NOT LIKE '%~%' AND CTP_SESSION_ID IS NULL;
UPDATE A
SET ORDER_INFO = OREPLACE(ORDER_INFO,'%','~')
WHERE ORDER_INFO NOT LIKE '%~%'
AND CTP_SESSION_ID IS NULL;

PostgreSQL checking for empty array changes behavior in Golang

I'm trying to implement the behavior of selecting data based on either an array of input, or get all data if array is null or empty.
SELECT * FROM table_name
WHERE
('{}' = $1 OR col = ANY($1))
This will return pq: op ANY/ALL (array) requires array on right side.
If I run
SELECT * FROM table_name
WHERE
(col = ANY($1))
This works just fine and I get the contents I expected.
I can also use array_length but it will request me to assert what type of data is in $1. If I do (array_length($1::string[],1) < 1 OR col = ANY($1)), it seems to always return false on the array_length and go on to the col = ANY($1)
How can I return either JUST the values from $1 OR all if $1 is '{}' or NULL?
Got it:
($1::string[] IS NULL OR event_id = ANY($1))

update multiple attributes in jsonb using case statement psql

I am trying to update the jsonb column media, with two keys i.e
default** is of type jsonb and image_set is an array of jsonb.
Is there is solution for single select update statement to update both keys.
test_media table
id | media | name
----+-------------------------------------------------------------------------------------------------------------------------------------------------------+-------
2 | {"default": {"w1": "fff", "w2": "aaa", "w3": "ddd"}, "image_set": [{"w1": "fff", "w2": "aaa", "w3": "ddd"}, {"w1": "bbb", "w2": "rrr", "w3": "vvv"}]} | pooja
Updating image-set
Update test_media
set media = media #- ('{image_set,'||(select pos-1 from test_media, jsonb_array_elements(media->'image_set') with ordinality arr(value, pos) where name='pooja' and value->>'w1'='fff')
|| '}')::text[]
|| jsonb_set(media, '{default}', '{"w1": "bbb", "w2": "rrr", "w3": "vvv"}' )
where name='pooja';
Here, based on delete, I want to update the default and image_set together depends on different condition.default jsonb value is from image_set array. I tried using case statement but it is not working fine. Different conditions of delete are :
When the jsonb value, i want to delete is in default as well as in
image_set, it should delete that value from image set and update the
default with other value from image set.
If not so, it won't update default, just the image_set value will be
deleted.
If the value of array i.e image_set is 1 , then the media='{}' updated
to null json.
Tried two things updating separately, default and image_set.
Update test_media
set media = ( CASE
WHEN jsonb_array_length(media->'image_set')::int > 1
THEN (Select media #- ('{image_set,'||(select pos-1 from test_media , jsonb_array_elements(media->'image_set') with ordinality arr(value, pos) where name='pooja' and value->>'w1'='fff') || '}')::text[])
ELSE media = '{}'
END IF
)
where name='pooja';
Here, i got the error:CASE types boolean and jsonb cannot be matched
Secondly,
update test_media
set media = jsonb_set(media, '{default}', (select from (select CASE WHEN media->'default'->>'w1'='fff' AND jsonb_array_length(media->'image_set')::int >0 THEN (select media->'image_set'->0 from test_media where name='pooja' ) WHEN media->'default'->>'w1'='fff' AND jsonb_array_length(media->'image_set')::int = 0 THEN (select media - 'default' from test_media where name = 'pooja') END) As Sub), True)
where name='pooja';
I would be thankful if i get support for case statement using select update. Hope for a positive response. Thanks.
updating multiple jsonb column
update-multiple-values-in-a-jsonb-data

Update all rows where contains 5 keys

I have Ticket table that has some columns like this :
ID : int
Body : nvarchar
Type : int
I have many rows where the Body column has value like this :
IPAddress = sometext, ComputerName = sometext , GetID = sometext, CustomerName=sometext-sometext , PharmacyCode = 13162900
I want update all rows' Type column where the Body column has at least five of the following keys:
IPAddress, ComputerName, GetID, CustomerName, PharmacyCode
You could do it with a simple update statement like that
UPDATE Ticket
SET Type = 4
WHERE Body LIKE '%IPAddress%'
and Body LIKE '%ComputerName%'
and Body LIKE '%GetID%'
and Body LIKE '%CustomerName%'
and Body LIKE '%PharmacyCode%'
if you know the 'keys' are always in the same order you could concatenate the LIKE conditions like so
UPDATE Ticket
SET Type = 4
WHERE Body LIKE '%IPAddress%ComputerName%GetID%CustomerName%PharmacyCode%'
If you have the possibility to change the data model it would be much better to explode this key & value column into an own table and link it back to this table as it is done in a proper relational model.
If you could calculate number of key value pair by number of = present in your string you could use this query
Update tblname set col=val where len(colname) - len(replace(colname,'=','')>5
The where part actually gives number of equal signs present in your string.

Check if a value exists in a collection stored in XML data type column

I have an XML data type column called "tags".
In that, I am storing a collection, like so:
<ArrayOfString>
<string>personal</string>
<string>travel</string>
<string>gadgets</string>
<string>parenting</string>
</ArrayOfString>
I want to select all the rows, that have one of the values that I am looking for: for example, I want to select all rows in the table that have a tag "travel".
I know that this works, if I know the index of the value I am looking for:
select * from posts
where tags.value('(/ArrayOfString/string)[1]', 'nvarchar(1000)') = 'travel'
but this query works only if the tag "travel" is the 2nd item in the nodes. How do I check if a value exists, irrespective of the position it is in?
select *
from tags
where tags.exist('/ArrayOfString/string[. = "travel"]') = 1
Or like this if you want to check against a variable.
declare #Val varchar(10)
set #Val = 'travel'
select *
from tags
where tags.exist('/ArrayOfString/string[. = sql:variable("#Val")]') = 1
You can try something like this:
SELECT
*
FROM
dbo.Posts
WHERE
tags.exist('/ArrayOfString/string/text()[. = "travel"]') = 1
This will list all the rows that have "travel" in one of the strings in your XML