JSON string - include single quote in MySQL database - mysql

I have a JSON type filed in a MySQL table. But if the data value contains a single quote, it fails saying bad SQL grammar. Please find the SQL query:
We can resolve this if we add escape character before single quotes. But is there any JSON function available in MYSQL which can be readily used? We have to supply the query from another application written in Java and we would not like to modify the program if possible.
INSERT INTO integration.staging_correspondence_inbound_invoice (correlation_id,interface_name,event_status,event_context,created_by,created_date) values ('1540626495812-0-1','invoice','EXCEPTION_CAUGHT',JSON_ARRAY('[ {
"exceptionRootCauseMessage" : "UpdateFailedException: Unable to update correspondence for correspondence id '68000'.Exception:{null\n> Record set for Correspondence with ids 68000 contains no records.\n>> }",
"inExchangeBody" : null,
"exceptionMessage" : "UpdateFailedException: Unable to update correspondence for correspondence id '68000'.Exception:{null\n> Record set for Correspondence with ids 68000 contains no records.\n>> }"
}, { }, {
"EXCEPTION_CAUGHT" : "Unable to update correspondence for correspondence id '68000'.Exception:{null\n> Record set for Correspondence with ids 68000 contains no records.\n>> }"
} ]'),'Integration_User',NOW())
We re using MySQL 5.7. In the above query, "event_context" is the JSON type field.

You can have a look at MySql Quote function. It should solve your problem.
As per documentation:
--> Quote --> ( --> str --> ) -->
The function achieves this by enclosing the string with single quotes,
and by preceding each single quote, backslash, ASCII NUL and control-Z
with a backslash.

Use base64
<?php
$json = base64_encode($json);
$sql = "UPDATE `entries` e SET e.fields = FROM_BASE64('".$json."') WHERE form_id = 163 AND e.fields LIKE '%$test_id%' LIMIT 1";
?>

Related

Unable to insert and save an escaped double quote in MySQL

I am trying to save JSON values in MySQL, but everytime the value contains double quotes, even if the query is properly written, MySQL manages to removed the escaped \"
For example:
INSERT into JSON_VALUES SET
ID = 150,
RESULT = '[{"ID":"150","VALUE":"THIS IS A \"TEST\" THAT IS IGNORED","DATE":"2021-08-26"}]'
After executing the query the inserted value in MySQL looks like this:
[{
"ID":"150",
"VALUE":"THIS IS A "TEST" THAT IS IGNORED",
"DATE":"2021-08-26"
}]
When "TEST" was supposed to be saved as \"TEST\"
Since TEST is not properly escpaed, the JSON value has a syntax error and becomes unreadable.
How do I force MySQL to preserve escaped content, or more precisely escaped double quotes?
I had the same issue some time ago. I had to use \\\" instead of \". In your case would be:
INSERT into JSON_VALUES SET
ID = 150,
RESULT = '[{"ID":"150","VALUE":"THIS IS A \\\"TEST\\\" THAT IS IGNORED","DATE":"2021-08-26"}]'

mySql JSON string field returns encoded

First week having to deal with a MYSQL database and JSON field types and I cannot seem to figure out why values are encoded automatically and then returned in encoded format.
Given the following SQL
-- create a multiline string with a tab example
SET #str ="Line One
Line 2 Tabbed out
Line 3";
-- encode it
SET #j = JSON_OBJECT("str", #str);
-- extract the value by name
SET #strOut = JSON_EXTRACT(#J, "$.str");
-- show the object and attribute value.
SELECT #j, #strOut;
You end up with what appears to be a full formed JSON object with a single attribute encoded.
#j = {"str": "Line One\n\tLine 2\tTabbed out\n\tLine 3"}
but using JSON_EXTRACT to get the attribute value I get the encoded version including outer quotes.
#strOut = "Line One\n\tLine 2\tTabbed out\n\tLine 3"
I would expect to get my original string with the \n \t all unescaped to the original values and no outer quotes. as such
Line One
Line 2 Tabbed out
Line 3
I can't seem to find any JSON_DECODE or JSON_UNESCAPE or similar functions.
I did find a JSON_ESCAPE() function but that appears to be used to manually build a JSON object structure in a string.
What am I missing to extract the values to the original format?
I like to use handy operator ->> for this.
It was introduced in MySQL 5.7.13, and basically combines JSON_EXTRACT() and JSON_UNQUOTE():
SET #strOut = #J ->> '$.str';
You are looking for the JSON_UNQUOTE function
SET #strOut = JSON_UNQUOTE( JSON_EXTRACT(#J, "$.str") );
The result of JSON_EXTRACT() is intentionally a JSON document, not a string.
A JSON document may be:
An object enclosed in { }
An array enclosed in [ ]
A scalar string value enclosed in " "
A scalar number or boolean value
A null — but this is not an SQL NULL, it's a JSON null. This leads to confusing cases because you can extract a JSON field whose JSON value is null, and yet in an SQL expression, this fails IS NULL tests, and it also fails to be equal to an SQL string 'null'. Because it's a JSON type, not a scalar type.

REGEX for selecting multiple value in string

I need an sql select statement to retrieve 04:30 and test.zip from this string:
{"TIME":"04:30","DATE":"11\/25\/2013","FILENAME":["test.zip"]}
use this \[(.*?)\]
it return value between [ and ]
and for 04:30 use TIME":(.*?),
it return value after "TIME":
Can't you just decode it and use PHP? (assuming you can't change the way it's stored in the db)
<?php
$str = '{"TIME":"04:30","DATE":"11/25/2013","FILENAME":["test.zip"]}';
$o = json_decode($str);
$time = $o->TIME;
$file = $o->FILENAME[0];
var_dump($time); //"04:30"
var_dump($file); //"test.zip"
Regex replaces etc in MySQL require a UDF (user-defined function) mysql-udf-regexp
If none of the above are viable solutions (change DB structure, do it with PHP, use a MySQL UDF), you'll need to get creative. It would require a known, static format of that string, but you could replace some parts and substring others. For example:
SELECT SUBSTRING(REPLACE(`column_name`,'{"TIME":"',''),1,5) AS `time` FROM `table_name`
File is more complex, this example assuming only one filename in the array
SELECT REPLACE(SUBSTRING(`column_name`,LOCATE('"FILENAME":["',`column_name`)+13),'"]}','') AS `file` FROM `table_name`
Those two field selections get 04:30 and test.zip respectively (you can of course use those functions in the same statement, rather than separately like I have, by comma separating them)

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.

A MySQL field value starting with a Numeral then followed by characters is treated as Numeric

I have a users table(MySQL) and the unique id is an AI field(user_id). I have a function to get the name of a user from the database, and the only parameter passed to it is the user_id.
Lets say the name of the user with user_id=8 is "Jony Bravo".
Here's my function:
function getName($user_id)
{
$sql="SELECT name FROM users WHERE user_id='$user_id'";
$result=mysql_query($sql) or die(mysql_error());
$row=mysql_fetch_assoc($result);
return ($row['name']);
}
both the function calls below return the same value: "Jony Bravo"!
echo getName(8);
echo getName('8k');
It's not just k, any characters after the numeral seem to be ignored. Kindly help.
If you try this:
SELECT 8='8k'
you can see that it returns true! That's because 8 is a int, and 8k is a string, and 8k converted to int becomes 8.
This returns false instead:
SELECT CAST(8 as char)='8k'
So you have to write your query like this:
SELECT name FROM users WHERE CAST(user_id as char)='$user_id'
Or you have to make sure that $user_id is numeric, and remove ':
SELECT name FROM users WHERE user_id=$user_id
The ID I imagine is Integer. If so when the string '8k' is converted to int all the non numerical charters are ignored and you are left with 8. Pass '2k' to the function and if you get the second record that means I'm correct. But this is bad practise you should not pass strings to function that must accept only integers.