Get a Table's Character Set - mysql

In MySQL, I can get a table's name, engine and collation like so:
SELECT TABLE_NAME, TABLE_SCHEMA, ENGINE, TABLE_COLLATION
FROM information_schema.tables
WHERE table_name = 'tbl_name';
But how how do I get a table's character set, not just collation? Is it possible to get it from information_schema.tables?

Each collation is used for only one character set, so it's not necessary to record the character set in the INFORMATION_SCHEMA.TABLES. The table collation is enough to indicate both the collation and the character set unambiguously.
You can check INFORMATION_SCHEMA.COLLATIONS or INFORMATION_SCHEMA.COLLATION_CHARACTER_SET_APPLICABILITY to get the mapping from a given collation to its character set.

Try running this:
SELECT default_character_set_name FROM information_schema.SCHEMATA S WHERE schema_name = "DBNAME";

Related

COLLATION 'utf8_bin' is not valid for CHARACTER SET 'utf8mb4'

I am trying to add emoji like 😋 in my application. In order to make it work, I have to use charset : 'utf8mb4' in database connection. But then my other search query doesn't work and throughs error like this
select id, full_name, profile_pic from users where school_id = 1 and exists (select * from groupmembers where (group_id = '110') and (users.id = groupmembers.user_id)) and full_name like '%d%' COLLATE utf8_bin - ER_COLLATION_CHARSET_MISMATCH: COLLATION 'utf8_bin' is not valid for CHARACTER SET 'utf8mb4
How can I make both works together? I am using adonis.js framework and it uses knex query/
Collations are specific to a character set. If your character set is utf8mb4, then you could use collation utf8mb4_bin but not utf8_bin.
This will become a bit more confusing someday, because MySQL has the intention to change the name of utf8mb4 to utf8. Cf. https://dev.mysql.com/doc/refman/8.0/en/charset-unicode-utf8.html
You can check all the collations allowed by this query:
select collation_name
from information_schema.collation_character_set_applicability
where character_set_name = ##character_set_connection;

Illegal mix of collations when running stored procedure

I have a very long stored procedure and I keep getting the following error:
Illegal mix of collations (utf8mb4_general_ci,COERCIBLE) and (latin1_swedish_ci,IMPLICIT) for operation '='
It's occurring on some databases but not others but when I run SHOW TABLE STATUS, all of the collations are set to latin1_swedish_ci
Does anyone have any advice on how to debug this? Is there a way to determine where in the stored procedure the error is coming from so I can try to pinpoint the issue?
In MySQL, collation can be set at different levels.
Database level
Table level
Column level
Apart from that collation can also be set at the server and connection level to MySQL.
Therefore, Check the collation type on various levels and make sure that they have the same collation. You can check the collation by:
Database collation
SELECT default_collation_name FROM information_schema.schemata WHERE schema_name = '<schema_name>';
Table collation
SELECT table_schema, table_name, table_collation FROM information_schema.tables WHERE table_schema = '<schema_name>';
Column collation
SELECT table_schema, table_name, column_name, collation_name FROM information_schema.columns WHERE table_schema = '<schema_name>';
Collation for the server, connection, and database
SHOW VARIABLES LIKE 'collation%';

MySql VIEW created with charset latin1 all configs are set to utf8

I'm trying to create a simple view but I'm getting error because the view is created with latin1 instead of utf8.
The View looks something like this:
create or replace view
my_view
as
select * from my_table
group by some_field
collate utf8_unicode_ci
;
The error I'm getting is:
COLLATION 'utf8_unicode_ci' is not valid for CHARACTER SET 'latin1'
What I did, was check multiple configuration options:
Global
show variables like "%char%";
character_set_client,utf8
character_set_connection,utf8
character_set_database,utf8
character_set_filesystem,binary
character_set_results,utf8
character_set_server,utf8
character_set_system,utf8
The table I'm using to create the view:
SELECT TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME, TABLE_COLLATION
FROM INFORMATION_SCHEMA.TABLES
where TABLE_NAME in ('my_table');
;
def,my_database,my_table,utf8_unicode_ci
The Columns of that table:
SELECT TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME, COLLATION_NAME
FROM INFORMATION_SCHEMA.COLUMNS
where TABLE_NAME in ('my_table');
def,my_database,my_table,id,null
def,my_database,my_table,active,null
def,my_database,my_table,title,utf8_unicode_ci
I had the same issue in an MySQL database, where I had Umlauts/special charaters within a CASE like this (reduced sample):
CASE
WHEN cfs.value = "ungeklärt" THEN "" -- the character 'ä' was an issue for me here
ELSE cfs.value
END AS "Category"
The error popped up for me, when savin this statement as a view.
Can you check if it solves the issue for you, when you set the names accordingly first? In my case this was latin1 instead of utf8 due to an old legacy database.
set names latin1;
If I understood your case correclty it would be this for you instead:
set names utf8;

Information Schema showing two character encodings for column

I'm in the process of migrating a MySQL database from the utf8 character set to uft8mb4, following this guide (https://mathiasbynens.be/notes/mysql-utf8mb4). For one of the tables I updated (table1) I get weird output from the information_schema. table1 has four columns, each listed below:
data_store VARCHAR(24)
data_group VARCHAR(24)
source_count INT
load_count INT
I have validated that only 4 columns appear through SELECT * on the table. However, running the following query on information_schema produces odd output.
SELECT column_name, character_set_name FROM information_schema.COLUMNS
WHERE table_name = "table1";
COLUMN_NAME CHARACTER_SET_NAME
--------------------------------------------------------------------------------------
data_store utf8
data_group utf8
source_count <null>
load_count <null>
data_store utf8mb4
data_group utf8mb4
source_count <null>
load_count <null>
I don't see duplicate rows (with differing character sets) for any other table that I have updated and am at a loss in regards to what is wrong and/or how to fix it. Any help would be much appreciated!
Notes: I believe I could just remove the unwanted columns from information_schema, but I'm not sure if this would break anything.
I think you're seeing the columns from different table1 tables in several different database schemas.
Try this to verify that claim.
SELECT table_schema, column_name, character_set_name
FROM information_schema.COLUMNS
WHERE table_name = 'table1'
Try this query to filter by the current database.
SELECT column_name, character_set_name
FROM information_schema.COLUMNS
WHERE table_name = 'table1'
AND table_schema = DATABASE()
Do not try to alter the INFORMATION_SCHEMA database in any way. Don't delete rows, don't add columns, or anything else. It's supposed to be readonly. But sometimes it isn't, and altering it can trash your MySQL instance. Don't ask me how I know that. :-)

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