Am getting the below error when trying to do a select through a stored procedure in MySQL.
Illegal mix of collations (latin1_general_cs,IMPLICIT) and
This code needs to be put inside Run SQL query/queries on database
SQL QUERY WINDOW
ALTER TABLE `table_name` CHANGE `column_name` `column_name` VARCHAR(128) CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL DEFAULT NULL;
Please replace table_name and column_name with appropriate name.
Below solution worked for me.
CONVERT( Table1.FromColumn USING utf8) = CONVERT(Table2.ToColumn USING utf8)
Solution if literals are involved.
I am using Pentaho Data Integration and dont get to specify the sql syntax. Using a very simple DB lookup gave the error "Illegal mix of collations (cp850_general_ci,COERCIBLE) and (latin1_swedish_ci,COERCIBLE) for operation '='"
The generated code was "SELECT DATA_DATE AS latest_DATA_DATE FROM hr_cc_normalised_data_date_v WHERE PSEUDO_KEY = ?"
Cutting the story short the lookup was to a view and when I issued
mysql> show full columns from hr_cc_normalised_data_date_v;
+------------+------------+-------------------+------+-----+
| Field | Type | Collation | Null | Key |
+------------+------------+-------------------+------+-----+
| PSEUDO_KEY | varchar(1) | cp850_general_ci | NO | |
| DATA_DATE | varchar(8) | latin1_general_cs | YES | |
+------------+------------+-------------------+------+-----+
which explains where the 'cp850_general_ci' comes from.
The view was simply created with 'SELECT 'X',......' According to the manual literals like this should inherit their character set and collation from server settings which were correctly defined as 'latin1' and 'latin1_general_cs' as this clearly did not happen I forced it in the creation of the view
CREATE OR REPLACE VIEW hr_cc_normalised_data_date_v AS
SELECT convert('X' using latin1) COLLATE latin1_general_cs AS PSEUDO_KEY
, DATA_DATE
FROM HR_COSTCENTRE_NORMALISED_mV
LIMIT 1;
now it shows latin1_general_cs for both columns and the error has gone away. :)
I had a similar problem, was trying to use the FIND_IN_SET procedure with a string variable.
SET @my_var = 'string1,string2';
SELECT * from my_table WHERE FIND_IN_SET(column_name,@my_var);
and was receiving the error
Error Code: 1267. Illegal mix of collations (utf8_unicode_ci,IMPLICIT) and (utf8_general_ci,IMPLICIT) for operation 'find_in_set'
Short answer:
No need to change any collation_YYYY variables, just add the correct collation next to your variable declaration, i.e.
SET @my_var = 'string1,string2' COLLATE utf8_unicode_ci;
SELECT * from my_table WHERE FIND_IN_SET(column_name,@my_var);
Long answer:
I first checked the collation variables:
mysql> SHOW VARIABLES LIKE 'collation%';
+----------------------+-----------------+
| Variable_name | Value |
+----------------------+-----------------+
| collation_connection | utf8_general_ci |
+----------------------+-----------------+
| collation_database | utf8_general_ci |
+----------------------+-----------------+
| collation_server | utf8_general_ci |
+----------------------+-----------------+
Then I checked the table collation:
mysql> SHOW CREATE TABLE my_table;
CREATE TABLE `my_table` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`column_name` varchar(40) COLLATE utf8_unicode_ci DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=125 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
This means that my variable was configured with the default collation of utf8_general_ci while my table was configured as utf8_unicode_ci.
By adding the COLLATE command next to the variable declaration, the variable collation matched the collation configured for the table.
I personnaly had this problem in a procedure.
If you dont want to alter table
you can try to convert your parameter into the procedure .
I've try sevral use of collate (with a set into the select) but none works for me.
CONVERT(my_param USING utf32)
did the trick.
I used ALTER DATABASE mydb DEFAULT COLLATE utf8_unicode_ci;
, but didn't work.
In this query:
Select * from table1, table2 where table1.field = date_format(table2.field,'%H');
This work for me:
Select * from table1, table2 where concat(table1.field) = date_format(table2.field,'%H');
Yes, only a concat
.