base64 decode a mysql column before performing a WHERE - mysql

Basically - its a long story - but I have a field in a database that is encoded as a base64 string.
EG: this is stored in the database:
YToyOntzOjIwOiJUeXBlX29mX29yZ2FuaXNhdGlvbiI7czoyMDoiTWVtYmVyIG9mIFBhcmxpYW1lbnQiO3M6ODoiUG9zdGNvZGUiO3M6NzoiUEUxIDFKQSI7fQ==
Which equals this:
a:2:{s:20:"Type_of_organisation";s:20:"Member of Parliament";s:8:"Postcode";s:7:"#postcode#";}
What I want to be able to do is select where this string LIKE '%Member of Parliament%'. Is there any way to base64 decode a mysql column before performing a WHERE?
eg: SELECT * FROM table WHERE base64_decode(column) LIKE '%Member of Parliament%'
Thanks

If you're using MySQL 5.6.1 or higher you can use the FROM_BASE64() function:
Takes a string encoded with the base-64 encoded rules used by TO_BASE64() and returns the decoded result as a binary string. The result is NULL if the argument is NULL or not a valid base-64 string. See the description of TO_BASE64() for details about the encoding and decoding rules.
This function was added in MySQL 5.6.1.
mysql> SELECT TO_BASE64('abc'), FROM_BASE64(TO_BASE64('abc'));
-> 'JWJj', 'abc'
http://dev.mysql.com/doc/refman/5.6/en/string-functions.html#function_from-base64
Otherwise you can use the User Defined Function from: https://github.com/y-ken/mysql-udf-base64

Related

Validate string before saving it to Mysql for chars taking more than 3 bytes

The Mysql db I am using has char encoding utf8 but certain sets of chars which take beyond 3 bytes are not getting saved. I could have changed the encoding to utf8mb4 but that is not an option. All I want to do is validate a string to check if the string will get saved in Mysql. I don't want to unnecessarily limit my chars to ASCII. How do I check if a char will take more than three bytes?
Plan A:
In your app language, convert your string to hex. Then look for f0. That byte would indicate utf8mb4 is needed.
In MySQL, the expression is HEX(col) REGEXP '^(..)*f0'.
Plan B:
Attempt to insert your text into a CHARACTER SET utf8 column of a spare table. Read it back and see if it matches. Storing a 4-byte character will either turn it into question marks or truncate the string. Either way, it won't match.
If you wish to insert the data in mysql query only rather than programmaticaly, then you can use the length() function to check for the byte length.
MySQL provides the LENGTH function to get a length of a string in bytes, and the CHAR_LENGTH function to get the length of a string in characters. If a string contains the multi-bytes character, the result of the LENGTH function is greater than the result of the CHAR_LENGTH() function
http://www.mysqltutorial.org/mysql-character-set/
Sample query follows
insert into x_table(data_string)
SELECT 'šč' as data_string where length('šč')<4
in Java check length before inserting into mysql
using
String s = new String("stringvalue");
byte[] bytes = s.getBytes("UTF-8");
System.out.println("bytes.length = "+bytes.length);
bytes.length can be checked before inserting (String.getBytes().length).

String to Blob comparison in MySQL where clause

I have a table called messages with a column (BLOB) called message_text. I'm passing a value from the web app when a user sends a new message and I want to check if it's an exact duplicate message text.
SELECT count(message_id) FROM messages WHERE message_text = '$msgTxt' AND user_id = $userId
Where $msgTxt will be a formatted string like...
"Hello there. I don\'t know you.
I\'ve just made a new line. "
The problem is that the comparison isn't working and I'm never finding duplicates. Even if I literally copy/paste an existing value from the database and replace it with $msgTxt in my query I never get any results, and so I'm assuming there's something wrong with the way I'm comparing a blob to a string.
BLOB values are treated as binary strings (byte strings). They have the binary character set and collation, and comparison and sorting are based on the numeric values of the bytes in column values. String or Text values are treated as nonbinary strings (character strings). They have a character set other than binary, and values are sorted and compared based on the collation of the character set.
So, you have to convert either BLOB to String or String to BLOB and then compare both.
If you are using java,
Convert Blob to String
byte[] bdata = blob.getBytes(1, (int)blob.length());
String data1 = new String(bdata);
What API are you using to call MySQL? I see some backslashes, but need to verify that \ is not turning into \\, and that other escapings are not unnecessarily happening or not happening.
Which OS are you using? Windows, when reading stuff, likes to convert NL into CRLF, thereby making it so that it won't match.

MySQL 5.7 - Query to set the value of a JSON key to a JSON Object

Using MySQL 5.7, how to set the value of a JSON key in a JSON column to a JSON object rather than a string.
I used this query:
SELECT json_set(profile, '$.twitter', '{"key1":"val1", "key2":"val2"}')
from account WHERE id=2
Output:
{"twitter": "{\"key1\":\"val1\", \"key2\":\"val2\"}", "facebook": "value", "googleplus": "google_val"}
But it seems like it considers it as a string since the output escapes the JSON characters in it. Is it possible to do that without using JSON_OBJECT()?
There's a couple of options that I know of:
Use the JSON_UNQUOTE function to unquote the output (ie not cast it to string) as documented here
Possibly use the ->> operator and select a specific path, documented here
Has a lot of implications, but you could disable backslashes as an escape character. I haven't tried this, so I don't even know if that works, but it's mentioned in the docs
On balance, I'd either use the ->> operator, or handle the conversion on the client side, depending on what you want to do.

MYSQL | ENCODE() outputs blob instead of text

Im trying to encode a simple string by the ENCODE()-function. Using a string it gives me text as output. But using a field it gives me BLOB. How can I get around BLOB and output text for encoded fields?
Here's what happens:
SELECT ENCODE('myText,'myPw')
- Output: baddade4b04e // Goal = This + using fieldname
SELECT ENCODE(Field,'myPw') FROM myTable
- Output: [BLOB - 14B]
What I've tried:
SELECT CAST(ENCODE(Field,'myPw') AS CHAR(1000) CHARACTER SET utf8) FROM myTable
- Output: Empty rows!
SELECT CONVERT(ENCODE(Field,'myPw') USING utf8) FROM myTable
- Output: % (Output is 1-2 chars, cant be right)
Imagine I have a column user. Now I want "PaulPeter" being encoded the same regardless of whether Im encoding the string "PaulPeter" or the field user where the value is "PaulPeter".
Could anyone explain this to me? Thanks very much!
Encrypted string:
Encrypted field:
MySQL-Client-Version: 5.5.41
user: text utf8_bin
EDIT:
I got another question according decoding here: Click
After being able to encode, I got the same problem there with AES_Encryption. When I encrypt a string I get the output as a string. When encrypting a field with a string-value I get blob. :( Totally annoying.
Your user column is of type TEXT. Try casting just that column to CHAR:
SELECT AES_ENCRYPT(CAST(Field AS CHAR(1000)),'myPw') FROM myTable

how to query a blob data

I have a table like :
------------------------------
Test_Id Test_data
(String) (blob)
------------------------------
I want a query to retrieve all the Test_Id's for a matching Test_data.
To achieve something like : select * from test_table where Test_data = blobObject;
How can we do above ??
First: there's no such thing as a string in MySQL. Only char/varchar/text.
Well you could cast it as char for comparison like this:
select * from test_table where Test_data = CAST( blobObject AS CHAR );
what's probably better is to convert your string to a binary string, but this might not give you the right comparison if you expect string comparison behaviour... well best you have a look at the char functions here:
http://dev.mysql.com/doc/refman/5.0/en/cast-functions.html
You can use a hash function such as MD5
SELECT * FROM example_table WHERE MD5(blob_column) = 'a6a7c0ce5a93f77cf3be0980da5f7da3';
MySQL has data types which can store binary data. Not only char/varchar/text, but also BINARY/VARBINARY/BLOB.
See http://dev.mysql.com/doc/refman/5.5/en/blob.html
And it's usage is as simple as normal string type. But, escaping is required. and query length is must specified because binary data may contain NULL character in their contents.
Before MySQL 3.23 (I guess), There were only mysql_query(), mysql_escape_string(). Those function has no capability specifying query length. after BLOB has been introduced in MySQL, mysql_real_query() and mysql_real_escape_string() supported.
I found some examples for you. May this links help you!
http://zetcode.com/db/mysqlc/
http://bytes.com/topic/c/answers/558973-c-client-load-binary-data-mysql