Illegal Mix Of Collations While Comparing Datetime with String - mysql

I have created a MYSQL stored procedure that searches all columns of a table (parameter 1) to find if any of them contains a string (parameter 2). The problem is that when I compare a datetime column with a string that contains greek characters I get the following error:
SELECT * FROM my_table WHERE my_datetime LIKE '%ΕΛΛΗΝΙΚΑ%';
Illegal mix of collations for operation 'like'
The execution of the query is successful when I use latin characters. I know how to avoid checking columns based on their datatype, however I really want to be able to search for datetime strings as well. I use MySQL 5.5.24. The collation of the database is utf8_general_ci and the collation of the server is latin1_swedish_ci. I have tried the command SET NAMES utf8 before the query, with no luck though. Any ideas? Thanks.

I had a problem with similar query:
SELECT * FROM some_table WHERE some_date LIKE '%2012-01%';
The result was an "Illegal mix of collations" error.
Using simply DATE_FORMAT function helped:
SELECT * FROM some_table WHERE DATE_FORMAT(some_date, '%Y-%m-%d') LIKE '%2012-01%';

Related

How to get a default column value from MySQL 5.7 information_schema.columns with appropriate quoting?

I maintain Beekeeper Studio, an open source SQL GUI.
I have a problem with information_schema.columns in MySQL 5.7.
when running:
select * from information_schema.columns where table_name = ?`
It returns the COLUMN_DEFAULT, but it doesn't seem to differentiate between variables (eg CURRENT_TIMESTAMP), and a string 'foo'.
Is there a place I can get the 'real' default value with appropriate quoting?
What I expect:
CURRENT_TIMESTAMP
'foo'
Unfortunately, there's no metadata in the INFORMATION_SCHEMA that can tell you this in MySQL 5.7. You just have to know that for a DATETIME or TIMESTAMP column, CURRENT_TIMESTAMP is a special case.
It is treated as a special case in the code, so if you use SHOW CREATE TABLE, it outputs the literal string "CURRENT_TIMESTAMP" instead of a quoted datetime value.
https://github.com/mysql/mysql-server/blob/5.7/sql/sql_show.cc#L1402-L1411

Select with error Illegal mix of collations

I have mysql clause:
Select * from table where firstname like 'INPUT'
I'm trying enter INPUT for display error:
Illegal mix of collations (utf8mb4_unicode_ci,IMPLICIT) and (utf8_general_ci,COERCIBLE) for operation 'like'
I setted variable:
I'm tried enter emoji but still display error.
Can you help me in this case ?
You can try this query:
select * from table_name where firstname like 'INPUT';
table is a keyword so try giving the name of the table instead in the query.
The reason you get this error is because your column firstname is in the character set utf8 (alias for utf8mb3) which can not represent characters requiring 4 bytes (all emoji characters fall in this category).
One way to solve it is to change the character set on firstname to utf8mb4. This does however come with the drawback that you can only have a varchar be 191 characters long if it has an index on it.
alter table `table` modify `firstname` varchar(191) character set utf8mb4;

SELECT DISTINCT not working

Why does this query produce an "Duplicate entry" error?
TRUNCATE parim_firm_tag_names;
INSERT INTO parim_firm_tag_names (firm_tag_name_value)
SELECT DISTINCT sona
FROM parim_marksona;
Error message:
SQL Error (1062): Duplicate entry '1-??????? ??????' for key
'firm_tag_name_value'
As you can see, firm_tag_name_value has an unique index, I use DISTINCT select and I'm truncating all existing data from tag_names.
What could produce this error?
This could be happening because of different collations defined on both tables parim_firm_tag_names and parim_marksona as string comparisons using distinct may results in different values on case sensitive and case insensitive collation values.
You can check collation of columns using this query:
SHOW FULL COLUMNS FROM parim_marksona;
SHOW FULL COLUMNS FROM parim_firm_tag_names;
To avoid this error, you can convert collation of column sona to the collation of column firm_tag_name_value using COLLATE, while selecting the distinct values from table parim_marksona.
Assuming collation of column firm_tag_name_value as latin1_swedish_cs:
TRUNCATE parim_firm_tag_names;
INSERT INTO parim_firm_tag_names (firm_tag_name_value)
SELECT DISTINCT sona COLLATE latin1_swedish_cs
FROM parim_marksona;
This should work without errors.
For more details refer manual Column Character Set and Collation.
Different character sets between the two tables, perhaps?

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.

Illegal mix of collations error in MySql

Just got this answer from a previous question and it works a treat!
SELECT username, (SUM(rating)/COUNT(*)) as TheAverage, Count(*) as TheCount
FROM ratings WHERE month='Aug' GROUP BY username HAVING TheCount > 4
ORDER BY TheAverage DESC, TheCount DESC
But when I stick this extra bit in it gives this error:
Documentation #1267 - Illegal mix of
collations
(latin1_swedish_ci,IMPLICIT) and
(latin1_general_ci,IMPLICIT) for
operation '='
SELECT username, (SUM(rating)/COUNT(*)) as TheAverage, Count(*) as TheCount FROM
ratings WHERE month='Aug'
**AND username IN (SELECT username FROM users WHERE gender =1)**
GROUP BY username HAVING TheCount > 4 ORDER BY TheAverage DESC, TheCount DESC
The table is:
id, username, rating, month
Here's how to check which columns are the wrong collation:
SELECT table_schema, table_name, column_name, character_set_name, collation_name
FROM information_schema.columns
WHERE collation_name = 'latin1_general_ci'
ORDER BY table_schema, table_name,ordinal_position;
And here's the query to fix it:
ALTER TABLE tbl_name CONVERT TO CHARACTER SET latin1 COLLATE 'latin1_swedish_ci';
Link
Check the collation type of each table, and make sure that they have the same collation.
After that check also the collation type of each table field that you have use in operation.
I had encountered the same error, and that tricks works on me.
[MySQL]
In these (very rare) cases:
two tables that really need different collation types
values not coming from a table, but from an explicit enumeration, for instance:
SELECT 1 AS numbers UNION ALL SELECT 2 UNION ALL SELECT 3
you can compare the values between the different tables by using CAST or CONVERT:
CAST('my text' AS CHAR CHARACTER SET utf8)
CONVERT('my text' USING utf8)
See CONVERT and CAST documentation on MySQL website.
I was getting this same error on PhpMyadmin and did the solution indicated here which worked for me
ALTER TABLE table CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci
Illegal mix of collations MySQL Error
Also I would recommend going with General instead of swedish since that one is default and not to use the language unless your application is using Swedish.
I think you should convert to utf8
--set utf8 for connection
SET collation_connection = 'utf8_general_ci'
--change CHARACTER SET of DB to utf8
ALTER DATABASE dbName CHARACTER SET utf8 COLLATE utf8_general_ci
--change CHARACTER SET of table to utf8
ALTER TABLE tableName CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci
I also got same error, but in my case main problem was in where condition the parameter that i'm checking was having some unknown hidden character (+%A0)
When A0 convert I got 160 but 160 was out of the range of the character that db knows, that's why database cannot recognize it as character other thing is my table column is varchar
the solution that I did was I checked there is some characters like that and remove those before run the sql command
ex:- preg_replace('/\D/', '', $myParameter);
Check that your users.gender column is an INTEGER.
Try: alter table users convert to character set latin1 collate latin1_swedish_ci;
You need to change each column Collation from latin1_general_ci to latin1_swedish_ci
I got this same error inside a stored procedure, in the where clause. i discovered that the problem ocurred with a local declared variable, previously loaded by the same table/column.
I resolved it casting the data to single char type.
In short, this error is caused by MySQL trying to do an operation on two things which have different collation settings. If you make the settings match, the error will go away. Of course, you need to choose the right setting for your database, depending on what it is going to be used for.
Here's some good advice on choosing between two very common utf8 collations: What's the difference between utf8_general_ci and utf8_unicode_ci
If you are using phpMyAdmin you can do this systematically by working through the tables mentioned in your error message, and checking the collation type for each column. First you should check which is the overall collation setting for your database - phpMyAdmin can tell you this and change it if necessary. But each column in each table can have its own setting. Normally you will want all these to match.
In a small database this is easy enough to do by hand, and in any case if you read the error message in full it will usually point you to the right place. Don't forget to look at the 'structure' settings for columns with subtables in as well. When you find a collation that does not match you can change it using phpMyAdmin directly, no need to use the query window. Then try your operation again. If the error persists, keep looking!
The problem here mainly, just Cast the field like this cast(field as varchar) or cast(fields as date)
I had this problem not because I'm storing in different collations, but because my column type is JSON, which is binary.
Fixed it like this:
select table.field COLLATE utf8mb4_0900_ai_ci AS fieldName
Use ascii_bin where ever possible, it will match up with almost any collation.
A username seldom accepts special characters anyway.
If you want to avoid changing syntax to solve this problem, try this:
Update your MySQL to version 5.5 or greater.
This resolved the problem for me.
I have the same problem with collection warning for a field that is set from 0 to 1. All columns collections was the same. We try to change collections again but nothing fix this issue.
At the end we update the field to NULL and after that we update to 1 and this overcomes the collection problem.
Was getting Illegal mix of collations while creating a category in Bagisto. Running these commands (thank you #Quy Le) solved the issue for me:
--set utf8 for connection
SET collation_connection = 'utf8_general_ci'
--change CHARACTER SET of DB to utf8
ALTER DATABASE dbName CHARACTER SET utf8 COLLATE utf8_general_ci
--change category tables
ALTER TABLE categories CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci
ALTER TABLE category_translations CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci
In my case it was something strange. I read an api key from a file and then I send it to the server where a SQL query is made. The problem was the BOM character that the Windows notepad left, it was causing the error that says:
SQLSTATE[HY000]: General error: 1267 Illegal mix of collations (latin1_swedish_ci,IMPLICIT) and (utf8_general_ci,COERCIBLE) for operation '='
I just removed it and everything worked like a charm
You need to set 'utf8' for all parameters in each Function. It's my case:
SELECT username, AVG(rating) as TheAverage, COUNT(*) as TheCount
FROM ratings
WHERE month='Aug'
AND username COLLATE latin1_general_ci IN
(
SELECT username
FROM users
WHERE gender = 1
)
GROUP BY
username
HAVING
TheCount > 4
ORDER BY
TheAverage DESC, TheCount DESC;
Make sure your version of MySQL supports subqueries (4.1+). Next, you could try rewriting your query to something like this:
SELECT ratings.username, (SUM(rating)/COUNT(*)) as TheAverage, Count(*) as TheCount FROM ratings, users
WHERE ratings.month='Aug' and ratings.username = users.username
AND users.gender = 1
GROUP BY ratings.username
HAVING TheCount > 4 ORDER BY TheAverage DESC, TheCount DESC