Correct mysql syntax to change a column with collation - mysql

This line of code was generated automatically by phpmyadmin (perhaps an old version running on my company's website, but I don't want to deal with that right now):
ALTER TABLE `lc_error_logs` CHANGE `OneDetailedMessage` `OneDetailedMessage` VARCHAR(5000) CHARSET=latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL;
When attempt to execute that SQL, get error message via phpmyadmin:
Query error:
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MYSQL server version for the right syntax to user near '=latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL' at line 1.
I don't see what is wrong with the query, and would like to know what is wrong.
Notes:
All I did was change the VARCHAR length.
Works fine if I delete the column, then recreate it with these same settings. Is just something wrong with that ALTER TABLE syntax.
I can change INT columns in the same table (e.g. INT to SMALLINT), without any problems. Something about the COLLATE? But that is the collate we use throughout this DB.
mysql version: "5.5.47-0ubuntu0.14.04.1"
It doesn't matter what values I use for VARCHAR length. It doesn't matter what I attempt to change (e.g. changing column name has the same error.) And I've had this problem before on other tables. I've never been able to successfully alter a VARCHAR in this DB, if I specify collation. (Even though this is the default collation for this DB, generated automatically when I do not specify collation.)

ALTER TABLE `lc_error_logs` CHANGE `OneDetailedMessage` `OneDetailedMessage` VARCHAR(5000) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL;
try CHARACTER SET instead of CHARSET=

The problem is with the CHARSET/COLLATE part. If I remove that, the query works (uses the DB's defaults for charset and collation):
ALTER TABLE `lc_error_logs` CHANGE `OneDetailedMessage` `OneDetailedMessage` VARCHAR(5000) NULL DEFAULT NULL;
Or the equivalent, slightly simpler:
ALTER TABLE `lc_error_logs` MODIFY `OneDetailedMessage` VARCHAR(5000) NULL DEFAULT NULL;
NOTE:
I still don't know what the correct syntax is, or whether it is an issue with how the DB is set up. So if someone can supply an answer that works even with specification of collation, I will accept that answer. Otherwise, I will accept this answer, and move on.

Related

How to store weird chars in the correct way in a MySQL DB

I need to store some data in a MySQL table, but I got some problems with theese kind of characters: "ฤ" "รฆ" "ล" "ฤ•" (and so on)
Till now I had theese data stored in a SQLlite database and it was great because all was good, but now I'm trying to export it in a MySQL DB, but the strange chars are stored not in the good way, even if I tried different char encode. (UTF-8, UTF-16, latin blah blah)
Does anyone know the correct way to do so?
thanks a lot!!
utf8 needs to be established in about 4 places.
The column(s) in the database -- Use SHOW CREATE TABLE to verify that they are explicitly set to utf8, or defaulted from the table definition. (It is not enough to change the database default.)
The connection between the client and the server. See SET NAMES utf8.
The bytes you have.
If you are displaying the text in a web page, check the <meta> tag.
Either you can switch to BLOB datatype, or if you insist on using TEXT/VARCHAR/CHAR then you need to change charset of your table and database as shown below.
CREATE DATABASE mydbname
CHARACTER SET utf8
COLLATE utf8_general_ci;
USE mydbname;
CREATE TABLE `mytable` (
`data` varchar(200) COLLATE utf8_unicode_ci NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
If you already have a database with utf8 charset and collation set to utf8_general_ci then you can simply alter your table as mentioned below:
ALTER TABLE `mytable` CHANGE `data` `data` VARCHAR(100)
CHARSET utf8 COLLATE utf8_general_ci DEFAULT '' NOT NULL;

Emoji is not stored properly in MySQL 5.6 with collation utf8mb4

I am trying to store emoji to the database in my server. I am using AWS EC2 instance as server, my server details are listed below:
OS: ubuntu0.14.04.1
MySQL version: 5.6.19-0ubuntu0.14.04.1 - (Ubuntu)
Database client version: libmysql - mysqlnd 5.0.11-dev - 20120503
I created a database test and table emoji in the server with following SQL:
CREATE DATABASE IF NOT EXISTS `test` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
USE `test`;
CREATE TABLE IF NOT EXISTS `emoji` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`text` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 AUTO_INCREMENT=1;
When I tried to execute the following insert, a warning appears and data are not stored properly:
INSERT INTO `test`.`emoji` (`id` , `text`) VALUES (NULL , '๐Ÿ‘† ๐Ÿ‘‡ ๐Ÿ‘ˆ ๐Ÿ‘‰');
Inserted row id: 3
Warning: #1366 Incorrect string value: '\xF0\x9F\x91\x86 \xF0...' for column 'text' at row 1
The value stored in the text column is: ???? ???? ???? ????
The same scenario work for my local database and the values are stored properly. Almost all configurations are similar in my local except the OS (Windows).
I was able to recreate your issue using SqlWorkbench.
You're client most likely has established a connection to the db whose character set does not match the character set of the table:
run this statement before you run the insert statement to align the character set and collation of the connection:
SET NAMES utf8mb4 COLLATE utf8mb4_general_ci
Hope this helps, character sets can be tricky.
Trying to save emoji's in my existing database table using the following stack Node-Js 12.13.x , Mysql 5.6.
Way around:
Either follow this solution
Or change the column data type to BLOB i.e
ALTER TABLE table_name CHANGE column column BLOB NULL
Hope this trick will work for you!
Migration from MSSQL to MySQL using workbench always getting problem.
Workbench already sets utf8mb4, and still getting error.
Then i follow #Haisum Usman's suggestion:
Set column as Blob on migration sql generated.
Migrate data
Change column to LONGTEXT!
Lots of time invested to get this working.

Sense of command collate in create table sql

I understand function of command collate (a little). It is truth that I did not test if it is possible to have tables with various collation (or even various charset) inside one DB.
But I found that (at least in phpmyadmin) when I create any DB, I set its charset and collation - and if I miss this command in CREATE TABLE ..., then automatically will be set collation set in creation of DB.
So, my question is: What is sense of presence of command collate in sql of CREATE TABLE ... if it can be missing there - and is recommended to have collate in CREATE TABLE ... or is it irrelevant?
In SQL Server if you don't specify the COLLATE it is defaulted to what ever DB is set to. Thus there is no danger in not specifying.
In MySQL behavior is the same:
The table character set and collation are used as default values for
column definitions if the column character set and collation are not
specified in individual column definitions. MySQL Reference
Collate is only used when you want to specify to non-default value. If all you are using is English character set than you have nothing to worry about it. If you store data from multiple languages than you have specify specific collation to ensure what characters are stored correctly.

Display collation in create table output

I'm writing a set of SQL statements in MySQL to create and modify a few tables. I need to get my output to match a document of sample output exactly (this is for school).
When I show my create table statements, all varchar columns need to look like this:
`name` varchar(10) COLLATE utf8_unicode_ci DEFAULT NULL,
but they weren't showing the collation. I tried changing the declaration to
name varchar COLLATE utf8_unicode_ci DEFAULT NULL,
but this caused the output to show both the charset and collation, and I need to be showing just the collation. The sample output document was created on Unix, while I am on Windows, so this could be the source of the difference, but I need to know for sure.
Is there a way I can alter my queries to show collation or is this just a Unix Windows inconsistency?
To be honest, I doubt very much that anyone intends for you to obtain output that is identical verbatemโ€”it's more likely that they require it to be identical semantically. However, you might play around with the table's default charset/collation to see whether that makes a difference to the output obtained from SHOW CREATE TABLE:
ALTER TABLE foo CHARACTER SET utf8 COLLATE ut8_bin;
Failing that, it could be a difference between MySQL versions.

mysql: error code [1267]; Illegal mix of collations (latin1_general_cs,IMPLICIT) and (latin1_swedish_ci,IMPLICIT) for operation '='

I want to make the password column of my User table to be case sensitive in mysql.
Following is the description of the table:
/*Table: mst_user*/
FIELD TYPE COLLATION
------------- ------------ -----------------
user_id VARCHAR(100) latin1_swedish_ci
first_name VARCHAR(25) latin1_swedish_ci
last_name VARCHAR(25) latin1_swedish_ci
USER_PASSWORD VARCHAR(50) latin1_swedish_ci
user_status INT(11) (NULL)
version_id INT(11) (NULL)
active_status INT(11) (NULL)
user_type INT(11) (NULL)
To make the USER_PASSWORD field case sensitive I executed following query:
ALTER TABLE `mst_user` MODIFY `USER_PASSWORD` VARCHAR(50) COLLATE `latin1_general_cs`;
This worked and the field is now case sensitive.
But I have a store procedure which executes a SELECT query on this table to check if the user exists for the given credentials.
Stored Proc::
CREATE PROCEDURE `usp_password_verify`(ip_login_id VARCHAR(200),
ip_user_password VARCHAR(200),
INOUT success INT(1),
INOUT tbl_usr_password VARCHAR(100),
INOUT pkg_user_password VARCHAR(100))
BEGIN
SELECT COUNT(*)
INTO success
FROM mst_user
WHERE UPPER (user_id) = UPPER (ip_login_id)
AND USER_PASSWORD=ip_user_password;
SET tbl_usr_password = '';
SET pkg_user_password= '';
END$$
When I call this stored proc from my java code I am getting the following error:
**error code [1267]; Illegal mix of collations (latin1_general_cs,IMPLICIT) and (latin1_swedish_ci,IMPLICIT) for operation '='**
Can anyone help what is wrong with this?
Something that works as a simple query gives error while executing it in a stored proc!?
As documented under Collation of Expressions:
MySQL assigns coercibility values as follows:
[ deletia ]
The collation of a column or a stored routine parameter or local variable has a coercibility of 2.
[ deletia ]
MySQL uses coercibility values with the following rules to resolve ambiguities:
[ deletia ]
If both sides have the same coercibility, then:
If both sides are Unicode, or both sides are not Unicode, it is an error.
You could add an explicit COLLATE clause in your expression to force one of the operands to have an explicit collation with a lower coercibility value:
USER_PASSWORD=ip_user_password COLLATE 'latin1_general_cs'
You might even want to consider latin1_bin in this case?
In any event, you should not be storing passwords in plaintext. Instead, store salted hashes of your users' passwords and simply verify that the hash matches that which is stored.
I came here after facing the same error. After going through the solutions provided it became apparent that the COLLATION was the trigger for my error. My code was similar to the original question but my error was MySQL said: #1267 - Illegal mix of collations (utf8mb4_0900_ai_ci,IMPLICIT) and (utf8mb4_general_ci,IMPLICIT) for operation '='.
I was trying to collect the password and username too (currently no hashing) and I fixed it by explicitly adding the COLLATION for both parameters.
First code (the erratic code):
WHERE user.username = username
AND user.password = password
My current code (the working code):
WHERE user.username = username COLLATE utf8mb4_0900_ai_ci
AND user.password = password COLLATE utf8mb4_0900_ai_ci
Adding a collation only to the password to force a collation match to username or adding only to the username didn't work. Even though one parameter had the right collation to it already, it still had an error. So I added the same collation to both parameters and it worked.
Take note this is the actual COLLATION that is being used in my database already, but for some reason on procedure calls it wasn't consistent.
Please do remember to salt/hash your passwords when you are done, my code is still a work in progress.
I know it's a little bit late but if this could save someone half a day of swearing it's still worth putting it down.
So, my setup was like this: 10.1.22-MariaDB, utf8mb4_general_ci.
All good, I restored a dump of my database, all went OK.
The database was originally in utf8_general_ci, but for some reasons was restored as utf8_unicode_ci. Changed that back to utf8_general_ci and checked there were no artifacts in the database like columns or table definitions collated as utf8_unicode_ci instead of utf8_general_ci
Trying to update a specific table resulted in an illegal mix of collation without any apparent reasons.
It boiled down to be in fact not the table itself but the associated trigger.
In fact the trigger called a procedure that had no collation info in my database, but that had a utf8_unicode_ci collation in information_schema.ROUTINES.DATABASE_COLLATION.
Recreating the procedure in the context of the new database collation solved my issue.
So after struggling with this error:
ERROR 1267 (HY000): Illegal mix of collations (utf8mb4_unicode_ci,COERCIBLE) and (utf8mb4_general_ci,COERCIBLE) for operation '='
I managed to fix this problem by changing the import database file from:
CHARSET utf8mb4 COLLATE utf8mb4_unicode_ci NO SQL
This is if you are importing functions/procedures/triggers, which my database had a ton of all of these features... I changed that to:
CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
I really hope this helps someone. I know the above was helpful, but it still took me a few hours to turn that into a solution. Thanks