MySQL query to append key:value to JSON string - mysql

My table has a column with a JSON string that has nested objects (so a simple REPLACE function cannot solve this problem) . For example like this: {'name':'bob', 'blob': {'foo':'bar'}, 'age': 12}. What is the easiest query to append a value to the end of the JSON string? So for the example, I want the end result to look like this: {'name':'bob', 'blob': {'foo':'bar'}, 'age': 12, 'gender': 'male'} The solution should be generic enough to work for any JSON values.

What about this
UPDATE table SET table_field1 = CONCAT(table_field1,' This will be added.');
EDIT:
I personally would have done the manipulation with a language like PHP before inserting it. Much easier. Anyway, Ok is this what you want? This should work providing your json format that is being added is in the format {'key':'value'}
UPDATE table
SET col = CONCAT_WS(",", SUBSTRING(col, 1, CHAR_LENGTH(col) - 1),SUBSTRING('newjson', 2));

I think you can use REPLACE function to achieve this
UPDATE table
SET column = REPLACE(column, '{\'name\':\'bob\', \'blob\': {\'foo\':\'bar\'}, \'age\': 12}', '{\'name\':\'bob\', \'blob\': {\'foo\':\'bar\'}, \'age\': 12, \'gender\': \'male\'}')
Take care to properly escape all quotes inside json
Upon you request of nested json, i think you can just remove last character of the string with SUBSTRING function and then append whatever you need with CONCAT
UPDATE table
SET column = CONCAT(SUBSTRING(column, 0, -1), 'newjsontoappend')

modify Jack's answer. Works perfectly even column value is empty on first update.
update table
set column_name = case when column_name is null or column_name =''
then "{'foo':'bar'}"
else CONCAT_WS(",", SUBSTRING(column_name, 1, CHAR_LENGTH(column_name) - 1),SUBSTRING("{'foo':'bar'}", 2))
end

Related

How replace "-" only in a *text* value of any generic jsonb in postgresql?

I need to clean JSON data that could look like:
{
"reference":"0000010-CAJ",
"product_code":"00000-10",
"var_name":"CAJ-1",
"doc_date":"2020-02-09T21:01:01-05:00",
"due_date":"2020-03-10T21:01:01-05:00",
}
However, this is just one of many other possibilities (is for a log aggregation that gets data from many sources).
I need to replace "-" with "_", but without break the dates like "2020-03-10T21:01:01-05:00", so can't simply cast to string and do a replace. I wonder if exist an equivalent of:
for (k,v) in json:
if is_text(v):
v = replace(...)
You can check with a regex if the value looks like a timestamp:
update the_table
set the_column = (select
jsonb_object_agg(
key,
case
when value ~ '^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}.*' then value
else replace(value, '-', '_')
end)
from jsonb_each_text(the_column) as t(key, value))
This iterates over all key/value pairs in the JSON column (using jsonb_each_text()) and assembles all of them back into a JSON again (using jsonb_object_agg()). Values that look like a timestamp are left unchanged, for all others, the - is replaced with a _.

prepend a string to a column value before specific character in MySQL

Imagine I have a table which has a Params column and it contains settings of my gallery. I want to add 2 other properties automatically with MySQL query.
I have already test this query but it will add my new properties at the first of the column value which is incorrect :
UPDATE table
SET params=CONCAT(', "slider_fullscreen_button_skin": "myTheme", "slider_zoompanel_skin": "myTheme"',params)
WHERE params NOT LIKE '%myTheme%';
let's say I have this value on my column :
{"title":"Bessariabian","alias":"Bessariabian","category":"1103","full_width":"false"}
I want my value change to something like this:
{"title":"Bessariabian","alias":"Bessariabian","category":"1103","full_width":"false", "slider_fullscreen_button_skin": "myTheme", "slider_zoompanel_skin": "myTheme"}
I want to make a query which adds the new properties at the end of the value before } location.
How I can handle this?
Use Substring_Index() function to get the Substring before the first occurence of }.
Now, Concat() this substring with your required string, and } at the end.
Try:
UPDATE table
SET params = CONCAT(
SUBSTRING_INDEX(params, '}', 1),
', "slider_fullscreen_button_skin": "myTheme", "slider_zoompanel_skin": "myTheme"',
'}'
)
WHERE params NOT LIKE '%myTheme%';

Replace Content using MySQL

In many of my column I have some data like this :
"Some Data. [content]Some Content[/content] Another Data"
I want to remove the substring which starts with [content] and ends with [/content]. The result should be :
"Some Data. Another Data"
I know it is possible by using MySQL replace() with Reg Ex but I don't how to use it.
Any help would be appreciated.
first get all the string between that string and after that you can able to replace it:
SELECT substring_index(substring_index(field, 'content', -1), '/content', 1) FROM table_name
after run this query, you get between string of [content] and [/content]
after that you just have to update one bye one using foreach loop with use of this query
UPDATE table_name SET field = REPLACE(field, 'content', 'content-that-will-replace-it') WHERE INSTR(field, 'content') > 0

REPLACE string in MySQL but only specified part

i would like to replace string in my query but only on the end of the string this is my example:
SET #exampleString = 'example_a_chapter_a';
SELECT REPLACE(#exampleString ,'_a','_b1');
Result what I get is this: example_b1_chapter_b1
But i would like this: example_a_chapter_b1
But there can be more time the '_a' in the string as this 'example_a_type_a_chapter_a', but
i would like to replace just the end '_a' of the string.
Thanks for you help
This will be tricky since MySQL can not replace by regex. One of possible ways is:
SELECT REPLACE(REPLACE(CONCAT(#exampleString, '#END'), '_a#END', '_b1'), '#END', '');
-i.e. add something that 100% is not in original string, to it's end and then replace.
Edit: second REPLACE is needed in case if original string doesn't end with _a (so you'll need to remove added #END)
You could not use replace() at all. Just reconstruct the string:
select (case when #exampleString like '%_a'
then concat(left(#exampleString, length(#exampleString) - length('_a')),
'_b1'
)
else #exampleString
end)
This has the advantage that it works even when the string doesn't end in '_a'.

Incrementing numerical value and changing string in SQL

I have a database that has stored values in a complicated, serialized array where one component is a string and another is the length of the characters of the string, in this format:
s:8:"test.com"
Where "s" holds the character length of the string in the quotations.
I would like to change the string from "test.com" to "testt.com", and I'm using the following statement in SQL:
UPDATE table SET row=(REPLACE (row, 'test.com','testt.com'))
However, this breaks the script in question, because it doesn't update the character length in the "s" preceding the string where "test.com" is stored.
I was wondering if there is a query I can use that would replace the string, and then also increment the value of this "s" preceding to where the replacement occurs, something like this:
UPDATE table SET row=(REPLACE (row, 's:' number 'test.com','s:' number+1 'testt.com'))
Does anyone know if this kind of query is even possible?
UPDATE table set row = concat('s:',length('testt.com'),':"testt.com"');
If you need to change exact string, then use exact query -
UPDATE table SET row = 's:9:"testt.com"' WHERE row = 's:8:"test.com"';
The string is a "serialized string".
If there are multiple strings to be replaced, it might be easier to create a script to handle this.
In PHP, it goes something like this:
$searchfor = serialize('test.com');
$replaceby = serialize('testt.com');
// strip last semicolon from serialized string
$searchfor = trim($searchfor,';');
$replaceby = trim($replaceby,';');
$query = "UPDATE table SET field = '$replaceby' WHERE field = '$searchfor';";
This way, you can create an exact query string with what you need.
Do fill in the proper code for db connection if necessary.