Convert VARCHAR to BINARY in MySQL - mysql

I have a table with VARCHAR(191) that actually uses a unique id which is constructed of 5 chars from these options: a-z, A-Z, 0-9 (example: 7hxYy)
I am performing a simple lookup with select * from table where token = 7hxYy yet I want the token to be case sensitive since I can actually query for 7hxyy and it will work.
How can I convert this column to binary without affecting the SQL select statements?

Try to modified the data type like:
alter table modify column token varchar(191) binary;
In MySQL, char vs char binary may affect the value case sensitive.
Or you can change your query sql like:
select * from table where BINARY `token`=‘7hxYy’;

Related

CONVERT to CHAR cause index on VARCHAR column doesn't work

SELECT * FROM table1 WHERE a = '1';
SELECT * FROM table1 WHERE a = CONVERT(1, CHAR);
Column a is VARCHAR type, and I have already created an index on it. The first one uses index but the second one doesn't. Any Clue on this?
I suspect that maybe MySQL takes CHAR and VARCHAR as two different types, so I changed column a to CHAR, and the index doesn't work either.
Sounds like a CHARACTER SET or COLLATION problem. Please provide:
SHOW VARIABLES LIKE 'char%';
how you are connecting to the database
SHOW CREATE TABLE table1;
Probably the answer involves changing the CONVERT:
CONVERT(1, CHAR charset utf8)
What is the real query; there may be some other approach that is better for your situation. Using CONVERT is a kludge; let's go to the need for it.
To see the conversion(s), do
EXPLAIN FORMAT=JSON SELECT ...

MySQL trying to apply UTF-8 encoding when trying to insert bytes to BLOB field

I'm using MySQL 8.0.4 (rc4) I need MySQL 8 because it's the only version of MySQL that supports CTEs.
My database is created thus:
CREATE DATABASE IF NOT EXISTS TestDB
DEFAULT CHARACTER SET utf8mb4
DEFAULT COLLATE utf8mb4_general_ci;
USE TestDB;
SET sql_mode = 'STRICT_TRANS_TABLES';
CREATE TABLE IF NOT EXISTS MyTable (
(...)
Body LONGBLOB NOT NULL,
(...)
);
When I try to insert raw byte data to this description field, I receive this error:
Error 1366: Incorrect string value: '\x8B\x08\x00\x00\x00\x00...' for column 'Body' at row 1.
This is the insert statement I'm using.
REPLACE INTO MyTable
SELECT Candidate.* FROM
(SELECT :Id AS Id,
(...)
:Body AS Body,
(...)
) AS Candidate
LEFT JOIN MyTable ON Candidate.Id = MyTable.Id
WHERE (
(...)
);
How could there be an incorrect string value for BLOB? Doesn't BLOB mean I can insert quite literally anything?
What's the : stuff? Why have the nested query? May we see actual SQL? What language are you using? It sounds like the "binding" tried to apply character set rules, when it should not. May we see the code that did the substitution of the : stuff?
BLOBs have not character set. As long as you can get the bytes past the parser, there should be no problem.
However, I find this to be a better way to do it...
In the app language, generate a hex string, then use that in
INSERT INTO ... VALUES (..., UNHEX(the-hex-string), ...)

MySQL transform case-sensitive unique field into unique case-insensitive field

This is an interesting challenge question as there can be multiple ways to solve this problem :)
I have an ID column that is unique but case-sensitive, ex:
----- ID ------
0018000001K6dkh -> record 1
0018000001K6dkH -> record 2 (different from record 1)
As MySQL is case insensitive in utf8, it is considering the two ID values as identical:
SELECT COUNT(*) FROM table WHERE id='0018000001K6dkh' //returns 2 instead of 1
SELECT COUNT(*) FROM table WHERE id='0018000001K6dkH' //returns 2 instead of 1
I need to build a MySQL function that I can apply to this column to transform all IDs into a case-insensitive and unique IDs, ex:
function('0018000001K6dkh') = something
function('0018000001K6dkH') = something different
function('0018000000ttzlB') = something even different
function('0018000000tTzlB') = something even more different
Note: I don't want to use collations, because I would have to change all the WHEREs and JOINs in my application (Laravel PHP). I want to change the IDs permanently.
According the official MySQL documentation you can set the collation on a per column basis (*see data_type section for CHAR, VARCHAR, TEXT, ENUM, and SET types).
This should change the default manner in which they are compared to string literals and each other, but I am not familiar with the rules used when comparing fields of differing collation with each other.
This is from mysql http://dev.mysql.com/doc/refman/5.7/en/case-sensitivity.html
To cause a case-sensitive comparison of nonbinary strings to be case
insensitive, use COLLATE to name a case-insensitive collation. The
strings in the following example normally are case sensitive, but
COLLATE changes the comparison to be case insensitive:
SET #s1 = 'MySQL' COLLATE latin1_bin;
SET #s2 = 'mysql' COLLATE latin1_bin;
SELECT #s1 = #s2;
return false
using #s1 COLLATE latin1_swedish_ci = #s2;
SELECT #s1 COLLATE latin1_swedish_ci = #s2;
return true
or use BINARY
SELECT COUNT(*) FROM table WHERE BINARY id='0018000001K6dkh'
SELECT COUNT(*) FROM table WHERE BINARY id='0018000001K6dkH'

SQL retrieve record if it has specific pattern

I have a DB which contains following column
message varchar(300) latin1_general_ci
I want to retrieve all messages which contain a specific string pattern, e.g. "#test".
The pattern (#test) may be anywhere in the string.
Is this possible with SQL or do I have to do this in PHP by iterating over all entries?
You can retrieve all such records by using following statement
SELECT * FROM `table_name` WHERE `message` LIKE '%#test%'
This query will return all records that contain #test anywhere in message field value
You can use the like keyword with wildcards.
where myfield like '%#test%'
The percentage sign is the wildcard.

How to check if a row in a table has muti-byte characters in it in a MySQL database?

I have a table which has column of descr which stores string values. Some of the values in descr has multi-byte characters in it and I want to know all those rows so I can remove those characters. How can I query the tables using MySQL functions to determine which rows have multi-byte characters. I am using MySQL version 5.1
SELECT ...
FROM yourtable
WHERE CHAR_LENGTH(descr) <> LENGTH(descr)
char_length is multi-byte aware and returns the actual character count. Length() is a pure byte-count, so a 3-byte char returns 3.
have you tried the collation and CHARSET functions on your descr column?
You can find the description of this functions here:
http://dev.mysql.com/doc/refman/5.1/en/information-functions.html
I think for your need it fits better the COERCIBILITY function. You can do something like:
select COERCIBILITY(descr, COLLATE utf8) from myTable;
and if this function returns 0 then you must edit the line.