I need to specify COLLATE in connection with LIKE inside a prepared statement inside a stored procedure, e.g. <col> LIKE ? COLLATE utf8_unicode_ci. I'm getting the following error:
COLLATION 'utf8_unicode_ci' is not valid for CHARACTER SET 'binary'
I have also tried to cast the parameter by all of: LIKE _utf8 ? COLLATE utf8_unicode_ci, LIKE CONVERT(? AS utf8) COLLATE utf8_unicode_ci and LIKE CAST(? AS varchar CHARACTER SET utf8) COLLATE utf8_unicode_ci but the error is then something like:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'varchar CHARACTER SET utf8) COLLATE utf8_unicode_ci ...
Any hint would be greatly appreciated.
AFAIK, the _utf8 is part of the syntax for string literals. Since you don't have, you cannot use it.
The signature for CAST() is this:
CAST(expr AS type)
I think you really want CONVERT():
CONVERT(expr,type), CONVERT(expr USING transcoding_name)
[...]
CONVERT() with USING converts data between different character sets.
In MySQL, transcoding names are the same as the corresponding
character set names. For example, this statement converts the string
'abc' in the default character set to the corresponding string in the
utf8 character set:
SELECT CONVERT('abc' USING utf8);
Related
Hello I'm trying to convert my database, one table and field to utf using this script
-- Write a script that converts hbtn_0c_0 database to UTF8
-- (utf8mb4, collate utf8mb4_unicode_ci) in your MySQL server.
-- You need to convert all of the following to UTF8:
-- Database hbtn_0c_0
-- Table first_table
-- Field name in first_table
ALTER DATABASE
`hbtn_0c_0`
CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci;
USE `hbtn_0c_0`;
ALTER TABLE
`first_table`
CONVERT TO CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci;
ALTER TABLE
`first_table`
CHANGE `name`
VARCHAR(256)
CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci;
But I have a SQL error. Please help me
black_genius#genius:~/Documents/ALX_Task/alx-higher_level_programming/0x0D-SQL_introduction$ cat 100-move_to_utf8.sql | mysql -hlocalhost -uroot -p
Enter password:
ERROR 1064 (42000) at line 22: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'VARCHAR(256)
CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci' at line 4
I'm using mysql version v8.0.31 on ubuntu 22.10
When you change a column, you need to provide the old name and the new name, even if the name is the same. See the syntax in the documentation:
CHANGE [COLUMN] old_col_name new_col_name column_definition
In your case it should be
ALTER TABLE
`first_table`
CHANGE `name` `name`
VARCHAR(256)
CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci;
Demonstration: . db-fiddle.com/f/qFuvFqP5PEGbsc8F8DfiaN/0
You don't need to change the individual column if you use ALTER TABLE ... CONVERT TO CHARACTER SET .... That ALTER TABLE automatically converts all string-based columns.
The documentation describes:
To change the table default character set and all character columns
(CHAR, VARCHAR, TEXT) to a new character set, use a statement like
this:
ALTER TABLE tbl_name CONVERT TO CHARACTER SET charset_name;
The statement also changes the collation of all character columns.
Paul Spiegel's answer about the CHANGE COLUMN syntax is correct; that syntax allows you to change a column's name, so you need to specify the column name twice.
An alternative is to use MODIFY COLUMN instead of CHANGE COLUMN. This allows you to change the column type and options, including character set, but not to change the column name. So there's no need to include the column name twice.
ALTER TABLE
`first_table`
MODIFY `name`
VARCHAR(256)
CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci;
But again, in your example, there's no need to use either CHANGE COLUMN or MODIFY COLUMN. The character set conversion should be achieved by using the CONVERT TO CHARACTER SET action.
I need a view with a constant value, which I'm executing with following code:
SELECT Name, 'Unpaid' AS Status FROM table;
However the collation is always by default utf8mb4_unicode_ci
I would need for this constant another collation with COLLATE but SELECT Name, 'Unpaid' COLLATE latin1_general_ci AS Status FROM table; doesn't work. Is there another way to change the collation to fix a illegal mix of collation?
You need to set both the character set and the collation. This should work:
select name, _latin1 'Unpaid' COLLATE latin1_general_ci as status
from t;
You might be interested in the documentation for character sets.
Here is the command I use:
ALTER TABLE <table_name> MODIFY <column_name> VARCHAR(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci;
It works well. Now I need to set utf8mb4_unicode_ci for a column (since currently characters are shown as ???). Anyway here is my new command:
ALTER TABLE <table_name> MODIFY <column_name> VARCHAR(255) CHARACTER SET utf8 COLLATE utf8mb4_unicode_ci;
But sadly MySQL throws:
ERROacR 1253 (42000): COLLATION 'utf8mb4_unicode_ci' is not valid for CHARACTER
Any idea?
The first part of the COLLATION name must match the CHARACTER SET name.
CHARACTER SET utf8mb4 is needed for Emoji and some Chinese characters.
Let's back up to the 'real' problem -- of question marks.
COLLATION refers to the rules of ordering and sorting, not encoding.
CHARACTER SET refers to the encoding. This should be consistent at all stages. Question Marks come from inconsistencies.
Trouble with UTF-8 characters; what I see is not what I stored points out that these are the likely suspects for Question Marks:
The bytes to be stored are not encoded as utf8/utf8mb4. Fix this.
The column in the database is not CHARACTER SET utf8mb4. Fix this if you need 4-byte UTF-8. (Use SHOW CREATE TABLE.)
Also, check that the connection during reading is UTF-8. The details depend on the application doing the connecting.
This worked for me:
ALTER TABLE <table_name> MODIFY <column_name> VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
I am trying to run a query which includes comparing an unicode string with some of the columns. For this, I need to change character-set and character-encoding for a column of type DATETIME. But when I execute following query:
ALTER TABLE licenses CHANGE expires_at expires_at DATETIME DEFAULT NULL CHARACTER SET utf8 COLLATE utf8_unicode_ci;
I get an error as:
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'CHARACTER SET utf8 COLLATE utf8_unicode_ci' at line 1
But for the following query (which alters character-set of a column of type VARCHAR) works perfectly fine:
ALTER TABLE customers CHANGE DEFAULT NULL name name VARCHAR(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci;
How can I change the character-set for a mysql column of type DATETIME?
I created a table and set the collation to utf8 in order to be able to add a unique index to a field. Now I need to do case insensitive searches, but when I performed some queries with the collate keyword and I got:
mysql> select * from page where pageTitle="Something" Collate utf8_general_ci;
ERROR 1253 (42000): COLLATION 'utf8_general_ci' is not valid for
CHARACTER SET 'latin1'
mysql> select * from page where pageTitle="Something" Collate latin1_general_ci;
ERROR 1267 (HY000): Illegal mix of collations (utf8_bin,IMPLICIT) and
(latin1_general_ci,EXPLICIT) for operation '='
I am pretty new to SQL, so I was wondering if anyone could help.
A string in MySQL has a character set and a collation. Utf8 is the character set, and utf8_bin is one of its collations. To compare your string literal to an utf8 column, convert it to utf8 by prefixing it with the _charset notation:
_utf8 'Something'
Now a collation is only valid for some character sets. The case-sensitive collation for utf8 appears to be utf8_bin, which you can specify like:
_utf8 'Something' collate utf8_bin
With these conversions, the query should work:
select * from page where pageTitle = _utf8 'Something' collate utf8_bin
The _charset prefix works with string literals. To change the character set of a field, there is CONVERT ... USING. This is useful when you'd like to convert the pageTitle field to another character set, as in:
select * from page
where convert(pageTitle using latin1) collate latin1_general_cs = 'Something'
To see the character and collation for a column named 'col' in a table called 'TAB', try:
select distinct collation(col), charset(col) from TAB
A list of all character sets and collations can be found with:
show character set
show collation
And all valid collations for utf8 can be found with:
show collation where charset = 'utf8'
Also please note that in case of using "Collate utf8_general_ci" or "Collate latin1_general_ci", i.e. "force" collate - such a converting will prevent from usage of existing indexes! This could be a bottleneck in future for performance.
Try this, Its working for me
SELECT * FROM users WHERE UPPER(name) = UPPER('josé') COLLATE utf8_bin;
May I ask why you have a need to explicitly change the collation when you do a SELECT? Why not just collate in the way you want to retrieve the records when sorted?
The problem you are having with your searches being case sensitive is that you have a binary collation. Try instead to use the general collation. For more information about case sensitivity and collations, look here:
Case Sensitivity in String Searches