PostgreSQL open JSONB column with slashes - postgresql

How is it possible to open the JSONB column where JSONB string with slashes?
"{\"id\":\"c39fe0f5f9b7c89b005bf3491f2a2ce1\",\"token\":\"c39fe0f5f9b7c89b005bf3491f2a2ce1\",\"line_items\":[{\"id\":32968150843480,\"properties\":{},\"quantity\":2,\"variant_id\":32968150843480,\"key\":\"32968150843480:4a6f6b7d19c7aef119af2cd909f429f1\",\"discounted_price\":\"40.00\",\"discounts\":[],\"gift_card\":false,\"grams\":0,\"line_price\":\"80.00\",\"original_line_price\":\"80.00\",\"original_price\":\"40.00\",\"price\":\"40.00\",\"product_id\":4638774493272,\"sku\":\"36457537-mud-yellow-28\",\"taxable\":false,\"title\":\"Knee Length Summer Shorts - Camel / 28\",\"total_discount\":\"0.00\",\"vendor\":\"Other\",\"discounted_price_set\":{\"shop_money\":{\"amount\":\"40.0\",\"currency_code\":\"USD\"},\"presentment_money\":{\"amount\":\"40.0\",\"currency_code\":\"USD\"}},\"line_price_set\":{\"shop_money\":{\"amount\":\"80.0\",\"currency_code\":\"USD\"},\"presentment_money\":{\"amount\":\"80.0\",\"currency_code\":\"USD\"}},\"original_line_price_set\":{\"shop_money\":{\"amount\":\"80.0\",\"currency_code\":\"USD\"},\"presentment_money\":{\"amount\":\"80.0\",\"currency_code\":\"USD\"}},\"price_set\":{\"shop_money\":{\"amount\":\"40.0\",\"currency_code\":\"USD\"},\"presentment_money\":{\"amount\":\"40.0\",\"currency_code\":\"USD\"}},\"total_discount_set\":{\"shop_money\":{\"amount\":\"0.0\",\"currency_code\":\"USD\"},\"presentment_money\":{\"amount\":\"0.0\",\"currency_code\":\"USD\"}}}],\"note\":null,\"updated_at\":\"2022-03-15T13:24:02.787Z\",\"created_at\":\"2022-03-15T13:23:31.912Z\",\"controller\":\"custom_webhooks\",\"action\":\"store_data\",\"custom_webhook\":{\"id\":\"c39fe0f5f9b7c89b005bf3491f2a2ce1\",\"token\":\"c39fe0f5f9b7c89b005bf3491f2a2ce1\",\"line_items\":[{\"id\":32968150843480,\"properties\":{},\"quantity\":2,\"variant_id\":32968150843480,\"key\":\"32968150843480:4a6f6b7d19c7aef119af2cd909f429f1\",\"discounted_price\":\"40.00\",\"discounts\":[],\"gift_card\":false,\"grams\":0,\"line_price\":\"80.00\",\"original_line_price\":\"80.00\",\"original_price\":\"40.00\",\"price\":\"40.00\",\"product_id\":4638774493272,\"sku\":\"36457537-mud-yellow-28\",\"taxable\":false,\"title\":\"Knee Length Summer Shorts - Camel / 28\",\"total_discount\":\"0.00\",\"vendor\":\"Other\",\"discounted_price_set\":{\"shop_money\":{\"amount\":\"40.0\",\"currency_code\":\"USD\"},\"presentment_money\":{\"amount\":\"40.0\",\"currency_code\":\"USD\"}},\"line_price_set\":{\"shop_money\":{\"amount\":\"80.0\",\"currency_code\":\"USD\"},\"presentment_money\":{\"amount\":\"80.0\",\"currency_code\":\"USD\"}},\"original_line_price_set\":{\"shop_money\":{\"amount\":\"80.0\",\"currency_code\":\"USD\"},\"presentment_money\":{\"amount\":\"80.0\",\"currency_code\":\"USD\"}},\"price_set\":{\"shop_money\":{\"amount\":\"40.0\",\"currency_code\":\"USD\"},\"presentment_money\":{\"amount\":\"40.0\",\"currency_code\":\"USD\"}},\"total_discount_set\":{\"shop_money\":{\"amount\":\"0.0\",\"currency_code\":\"USD\"},\"presentment_money\":{\"amount\":\"0.0\",\"currency_code\":\"USD\"}}}],\"note\":null,\"updated_at\":\"2022-03-15T13:24:02.787Z\",\"created_at\":\"2022-03-15T13:23:31.912Z\"}}"
this real JSONB column
I can not find any example of how to deal with this type of JSONB

Whatever is inserting your data is screwing it up. It is taking the string representation of a JSON object and stuffing that into a JSON string scalar. You need to fix that or it will just keep happening.
To fix what is already there, you need to extract the real PostgreSQL string out of the JSON string, then cast that to JSONB. Extracting a JSON string can be done unintuitively with #>>'{}', or even less intuitively with ->>0.
select (data#>>'{}')::jsonb from table_name.
Of course you should fix it permanently, not just do it on the fly all the time, which is both slow and confusing.
update table_name set data=(data#>>'{}')::jsonb;
Of course fixing the tool which screws this up in the first place, and fixing the historical data, need to be done in a coordinated fashion or you will have a glorious mess on your hands.

I think you have wrong formatted string in jsonb field. You can try fix it in next way:
select trim(both '"' from replace(data::varchar, '\"', '"'))::jsonb data from tbl;
PostgreSQL JSONB online

Related

Postgres JSONB values are all strings

Somehow populating a database with a JSONB column ended up with every value in the column being a JSONB string instead of an object.
=> select specifications from checklist_item;
specifications
---------------------
"{}"
"{}"
"{\"x\": 2, \"y\": \"z\"}"
Is it possible to update, in a single statement, each of these values to JSONB objects as opposed to strings?
I tried to_jsonb(specifications) but that did not parse as expected. I've gone over documentation but all the examples seem to show ways to manipulate data that is already a jsonb array or a jsonb object but not a plain string.
I can write a script and do the parsing in Python, but there certainly must be a nice way to do with in a single update command with a json function that I simply cannot find at the moment. Is there such a json function or operator that will "parse" my bad data?
to_jsonb(specifications) does to_jsonb(specifications::text), which just gets the JSON text with the string literal as text. What you need is to get the value of the JSON string literal, then cast that to jsonb:
UPDATE checklist_item
SET specifications = (specifications #>> '{}')::jsonb
-- or … = to_jsonb(specifications #>> '{}')
WHERE jsonb_typeof(specifications) = 'string';

extract text from string data using SQL (with handing null values)

I have issue with extracting text from string data using T-SQL. I have following data and text that I would like to extract (value between second and third underscore:
sss_ss_d_a -> d
aaa_dd_b -> b
aaa_aa -> NULL
I know that there is a lot of similar topics, but I have problem especially with handling NULLs and situation when there are no delimiter after desired value
Thank you very much for your help, regards
Try it like this:
Some sample data in a declared table
DECLARE #tbl TABLE(YourString VARCHAR(100));
INSERT INTO #tbl VALUES('sss_ss_d_a'),('aaa_dd_b'),('aaa_aa');
--The query
SELECT t.YourString
,CAST(CONCAT('<x>',REPLACE(t.YourString,'_','</x><x>'),'</x>') AS XML).value('/x[3]/text()[1]','nvarchar(max)')
FROM #tbl t;
The idea in short:
We replace the underscores with XML tags thus transforming the string to castable XML.
We use XQuery within .value to pick the third element.
Starting with v2016 the recommended approach uses JSON instead
(hint: we use "2" instead of "3" as JSON is zero-based).
,JSON_VALUE(CONCAT('["',REPLACE(t.YourString,'_','","'),'"]'),'$[2]')
The idea is roughly the same.
General hint: Both approaches might need escaping forbidden characters, such as < or & in XML or " in JSON. But this is easy...

Set nextval sequence data type to integer only

I have an issues running around my mind regarding default for 'id' field in my postgresql database. Here is the syntax:-
nextval('unsub_keyword_id_seq'::regclass)
However I'm not really understands even after read the documentations & I would like to set the value only for integer(digit only). I try to alter the column by change regclass to other OIDs but each time it will return errors.
Really appreciate if can get this solved very soon.
Update:
It just come to my idea on the data type for the column after I try & error with the code that will produce the id for the column.
Is integer(postgresql in this case) have it's own default length or not?
If I need to to insert long id, should I set the column length?
Kindly advise.
sorry if my questions quite confusing. your comments may help me to improve it.
From the comments:
I need to insert an id with length of 50 with consist of 2 alphabets & the rest is numeric. the problems occur as the data type is in integer & the data inserting in unsuccessful. is it possible to insert my desired data by retain the data type to integer?
If I understand this correctly, you probably need to format a string, e.g.
format('%s%s', 'XX', nextval('some_sequence_name'))

replacing characters in a CLOB column (db2)

I have a CLOB(2000000) field in a db2 (v10) database, and I would like to run a simple UPDATE query on it to replace each occurances of "foo" to "baaz".
Since the contents of the field is more then 32k, I get the following error:
"{some char data from field}" is too long.. SQLCODE=-433, SQLSTATE=22001
How can I replace the values?
UPDATE:
The query was the following (changed UPDATE into SELECT for easier testing):
SELECT REPLACE(my_clob_column, 'foo', 'baaz') FROM my_table WHERE id = 10726
UPDATE 2
As mustaccio pointed out, REPLACE does not work on CLOB fields (or at least not without doing a cast to VARCHAR on the data entered - which in my case is not possible since the size of the data is more than 32k) - the question is about finding an alternative way to acchive the REPLACE functionallity for CLOB fields.
Thanks,
krisy
Finally, since I have found no way to this by an SQL query, I ended up exporting the table, editing its lob content in Notepad++, and importing the table back again.
Not sure if this applies to your case: There are 2 different REPLACE functions offered by DB2, SYSIBM.REPLACE and SYSFUN.REPLACE. The version of REPLACE in SYSFUN accepts CLOBs and supports values up to 1 MByte. In case your values are longer than you would need to write your own (SQL-based?) function.
BTW: You can check function resolution by executing "values(current path)"

How to avoid trailing spaces in T-SQL

I store data in T-SQL server and use nchar fields to store string values.
The problem is that after selecting element from database I have very long string ended with spaces.
Can I set another field in database to avoid such situation, or have I do it in my ORM?
Rewrite the DB to store string values as nvarchar if it better represents your data.
If rewriting your DB is not possible or practical, then you have to trim the trailing spaces in your ORM.
Adding to the other answer. You can also deal with it in the select
RTRIM
A situation to use char or nchar is to prevent fragmentation.
If value starts null but you are going to later add a value then space is reserved.