after Mysql installation , I create a table and add some records like this
create table score (
student_id int,
subject varchar(10),
subject_score int
);
insert into score values (001,'数学',50),(002,'数学',60),(003,'数学',70);
and the result is
mysql> select * from score;
+------------+---------+---------------+
| student_id | subject | subject_score |
+------------+---------+---------------+
| 1 | ?? | 50 |
| 2 | ?? | 60 |
| 3 | ?? | 70 |
+------------+---------+---------------+
3 rows in set (0.00 sec)
and then I changed "character set"
mysql> alter table score character set utf8;
mysql> alter table score modify subject varchar(10) character set utf8;
mysql> set character_set_server=utf8;
mysql> SHOW VARIABLES LIKE 'character_set%';
+--------------------------+---------------------------------------------------------+
| Variable_name | Value |
+--------------------------+---------------------------------------------------------+
| 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 |
| character_sets_dir | /usr/local/mysql-5.5.47-linux2.6-x86_64/share/charsets/ |
+--------------------------+---------------------------------------------------------+
8 rows in set (0.00 sec)
and my table struture is
mysql> show create table score\G;
*************************** 1. row ***************************
Table: score
Create Table: CREATE TABLE `score` (
`student_id` int(11) DEFAULT NULL,
`subject` varchar(10) DEFAULT NULL,
`subject_score` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
I think everything is fine but when I query my table, Chinese character still cannot display correctly
mysql> select * from score;
+------------+---------+---------------+
| student_id | subject | subject_score |
+------------+---------+---------------+
| 1 | ?? | 50 |
| 2 | ?? | 60 |
| 3 | ?? | 70 |
+------------+---------+---------------+
3 rows in set (0.00 sec)
but when I insert the same records again , new record is fine!
mysql> insert into score values (001,'数学',50),(002,'数学',60),(003,'数学',70);
Query OK, 3 rows affected (0.00 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> select * from score;
+------------+---------+---------------+
| student_id | subject | subject_score |
+------------+---------+---------------+
| 1 | ?? | 50 |
| 2 | ?? | 60 |
| 3 | ?? | 70 |
| 1 | 数学 | 50 |
| 2 | 数学 | 60 |
| 3 | 数学 | 70 |
+------------+---------+-------
how to save my old records? I need somebody help and thank you very much
Use UTF-8 when you create table.
create table table_name () CHARACTER SET = utf8;
Use UTF-8 when you insert to table
set username utf8; INSERT INTO table_name (ABC,VAL);
Related
This question already has an answer here:
MySql - using dynamic table names in one query
(1 answer)
Closed 1 year ago.
I have a table generated from SQL Query itself. Now I need to add an auto incremental id column into this table.
Usual syntax to add auto incremental id column is-
ALTER TABLE *Table_Name* ADD id INT NOT NULL AUTO_INCREMENT PRIMARY KEY
But I don't have a specific table name, the table is generated from a query.
You can do it with a query like this:
## Your Query to generate the Tablename
SELECT "myTable" INTO #mytab;
EXECUTE IMMEDIATE CONCAT("ALTER TABLE ",#mytab," ADD id INT NOT NULL AUTO_INCREMENT PRIMARY KEY FIRST");
sample
MariaDB [bernd]> desc myTable;
+----------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------+---------+------+-----+---------+-------+
| insertat | date | YES | | NULL | |
| myval | int(11) | YES | | NULL | |
+----------+---------+------+-----+---------+-------+
2 rows in set (0.02 sec)
MariaDB [bernd]> select * from myTable;
+------------+-------+
| insertat | myval |
+------------+-------+
| 2021-01-01 | 44 |
| 2021-01-02 | 99 |
| 2021-01-02 | 134 |
| 2021-01-03 | 45 |
| 2021-01-04 | 2 |
| 2021-01-04 | 17 |
+------------+-------+
6 rows in set (0.06 sec)
MariaDB [bernd]> ## Your Query to generate the Tablename
MariaDB [bernd]> SELECT "myTable" INTO #mytab;
Query OK, 1 row affected (0.01 sec)
MariaDB [bernd]>
MariaDB [bernd]> EXECUTE IMMEDIATE CONCAT("ALTER TABLE ",#mytab," ADD id INT NOT NULL AUTO_INCREMENT PRIMARY KEY FIRST");
Query OK, 0 rows affected (0.14 sec)
Records: 0 Duplicates: 0 Warnings: 0
MariaDB [bernd]> desc myTable;
+----------+---------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+---------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| insertat | date | YES | | NULL | |
| myval | int(11) | YES | | NULL | |
+----------+---------+------+-----+---------+----------------+
3 rows in set (0.01 sec)
MariaDB [bernd]> select * from myTable;
+----+------------+-------+
| id | insertat | myval |
+----+------------+-------+
| 1 | 2021-01-01 | 44 |
| 2 | 2021-01-02 | 99 |
| 3 | 2021-01-02 | 134 |
| 4 | 2021-01-03 | 45 |
| 5 | 2021-01-04 | 2 |
| 6 | 2021-01-04 | 17 |
+----+------------+-------+
6 rows in set (0.00 sec)
MariaDB [bernd]>
While investigating an issue with a failing migration I found out the following strange behaviour. Using SET NAMES utf8 on my client session changes the behaviour of REPLACE(uuid(),'','') calls.
mysql> select replace(uuid(),'','') from mysql.user;
+--------------------------------------+
| replace(uuid(),'','') |
+--------------------------------------+
| 4b483d57-ecdc-11e8-844f-0242ac120002 |
| 4b483d57-ecdc-11e8-844f-0242ac120002 |
| 4b483d57-ecdc-11e8-844f-0242ac120002 |
+--------------------------------------+
3 rows in set (0.00 sec)
mysql> set names utf8;
Query OK, 0 rows affected (0.01 sec)
mysql> select replace(uuid(),'','') from mysql.user;
+--------------------------------------+
| replace(uuid(),'','') |
+--------------------------------------+
| 539c0b5c-ecdc-11e8-844f-0242ac120002 |
| 539c0b79-ecdc-11e8-844f-0242ac120002 |
| 539c0b7f-ecdc-11e8-844f-0242ac120002 |
+--------------------------------------+
3 rows in set (0.01 sec)
As you can see the generated UUID's are unique only after setting NAMES to utf8. The way I found out about SET NAMES utf8 was passing the query through MySQL Workbench.
I would greatly appreciate if someone here can explain how character sets (NAMES) influence the output of REPLACE(UUID(), ...) calls. Thanks in advance.
Update: adding a snippet to prove that the problem 1) is not with UUID() generating non-unique values and 2) relates to utf8mb4 charset
mysql> SHOW VARIABLES LIKE 'char%';
+--------------------------+----------------------------+
| Variable_name | Value |
+--------------------------+----------------------------+
| character_set_client | utf8mb4 |
| character_set_connection | utf8mb4 |
| character_set_database | utf8mb4 |
| character_set_filesystem | binary |
| character_set_results | utf8mb4 |
| character_set_server | utf8mb4 |
| character_set_system | utf8 |
| character_sets_dir | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
8 rows in set (0.01 sec)
mysql> select uuid, replace(uuid,'','') from ( select uuid() as uuid from mysql.user) tmp;
+--------------------------------------+--------------------------------------+
| uuid | replace(uuid,'','') |
+--------------------------------------+--------------------------------------+
| e41d2fe4-ed70-11e8-844f-0242ac120002 | e41d2dc2-ed70-11e8-844f-0242ac120002 |
| e41d3042-ed70-11e8-844f-0242ac120002 | e41d2dc2-ed70-11e8-844f-0242ac120002 |
| e41d309c-ed70-11e8-844f-0242ac120002 | e41d2dc2-ed70-11e8-844f-0242ac120002 |
+--------------------------------------+--------------------------------------+
3 rows in set (0.00 sec)
mysql> set names utf8;
Query OK, 0 rows affected (0.00 sec)
mysql> select uuid, replace(uuid,'','') from ( select uuid() as uuid from mysql.user) tmp;
+--------------------------------------+--------------------------------------+
| uuid | replace(uuid,'','') |
+--------------------------------------+--------------------------------------+
| e9059092-ed70-11e8-844f-0242ac120002 | e9059117-ed70-11e8-844f-0242ac120002 |
| e90591a1-ed70-11e8-844f-0242ac120002 | e905923e-ed70-11e8-844f-0242ac120002 |
| e9059380-ed70-11e8-844f-0242ac120002 | e90593e1-ed70-11e8-844f-0242ac120002 |
+--------------------------------------+--------------------------------------+
3 rows in set (0.00 sec)
mysql> set names utf8mb4;
Query OK, 0 rows affected (0.00 sec)
mysql> select uuid, replace(uuid,'','') from ( select uuid() as uuid from mysql.user) tmp;
+--------------------------------------+--------------------------------------+
| uuid | replace(uuid,'','') |
+--------------------------------------+--------------------------------------+
| ef564f32-ed70-11e8-844f-0242ac120002 | ef564d0c-ed70-11e8-844f-0242ac120002 |
| ef564fa4-ed70-11e8-844f-0242ac120002 | ef564d0c-ed70-11e8-844f-0242ac120002 |
| ef565019-ed70-11e8-844f-0242ac120002 | ef564d0c-ed70-11e8-844f-0242ac120002 |
+--------------------------------------+--------------------------------------+
3 rows in set (0.00 sec)
Update 2: Adding EXPLAIN queries below to trace the actual SQL code as suggested by #qbolec. That reveals that the use of CONVERT(... using ...) is the culprit for the non-unique UUIDs. I still do not exactly understand why as this is not the behaviour I expect from CONVERT() func.
mysql> set names utf8mb4;
Query OK, 0 rows affected (0.00 sec)
mysql> explain select replace(uuid(),'','') from mysql.user;\W
+----+-------------+-------+------------+-------+---------------+---------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+-------+---------------+---------+---------+------+------+----------+-------------+
| 1 | SIMPLE | user | NULL | index | NULL | PRIMARY | 276 | NULL | 7 | 100.00 | Using index |
+----+-------------+-------+------------+-------+---------------+---------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)
Note (Code 1003): /* select#1 */ select replace(convert(uuid() using utf8mb4),'','') AS `replace(uuid(),'','')` from `mysql`.`user`
Show warnings enabled.
mysql> set names utf8;
Query OK, 0 rows affected (0.00 sec)
mysql> explain select replace(uuid(),'','') from mysql.user;\W
+----+-------------+-------+------------+-------+---------------+---------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+-------+---------------+---------+---------+------+------+----------+-------------+
| 1 | SIMPLE | user | NULL | index | NULL | PRIMARY | 276 | NULL | 7 | 100.00 | Using index |
+----+-------------+-------+------------+-------+---------------+---------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)
Note (Code 1003): /* select#1 */ select replace(uuid(),'','') AS `replace(uuid(),'','')` from `mysql`.`user`
Show warnings enabled.
I am trying to insert some emoji characters into a table in MySQL, but values are stored as question marks (????).
I made sure to create the database with the proper utf8mb4 encoding:
mysql> describe users;
+-------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(191) | YES | | NULL | |
+-------+--------------+------+-----+---------+----------------+
2 rows in set (0.01 sec)
Then I tried to make sure, does MySql understand emoji or not, so I did this:
mysql> select '🌰';
+------+
| 🌰 |
+------+
| 🌰 |
+------+
1 row in set (0.00 sec)
Then I did this:
mysql> insert into users (name) values ('🌰');
Query OK, 1 row affected, 1 warning (0.05 sec)
mysql> select * from users;
+----+------------+
| id | name |
+----+------------+
| 21 | فاضل |
| 30 | سلاحف |
| 46 | ???? |
| 47 | ???? |
| 48 | ???? |
| 49 | ???? |
+----+------------+
6 rows in set (0.01 sec)
I don't know what to do to fix that..
** EDIT ** : as requested in the comments, I ran the following command:
mysql> SHOW VARIABLES LIKE 'character%';
+--------------------------+-------------------------+
| Variable_name | Value |
+--------------------------+-------------------------+
| character_set_client | utf8 |
| character_set_connection | utf8 |
| character_set_database | utf8mb4 |
| character_set_filesystem | binary |
| character_set_results | utf8 |
| character_set_server | utf8 |
| character_set_system | utf8 |
| character_sets_dir | /static/share/charsets/ |
+--------------------------+-------------------------+
8 rows in set (0.00 sec)
Your connection is set up for utf8; it needs to be set up for utf8mb4.
How did you set it? Change to whichever of these applies.
SET NAMES utf8mb4
PDO(... charset=utf8mb4)
mysqli::set_charset('utf8mb4')
etc
Emoji are 4-byte utf8 codes, hence the four question marks.
I am having issues inserting Id fields from two tables into a single record in a third table.
mysql> describe ing_titles;
+----------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+------------------+------+-----+---------+----------------+
| ID_Title | int(10) unsigned | NO | PRI | NULL | auto_increment |
| title | varchar(64) | NO | UNI | NULL | |
+----------+------------------+------+-----+---------+----------------+
2 rows in set (0.22 sec)
mysql> describe ing_categories;
+-------------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+------------------+------+-----+---------+----------------+
| ID_Category | int(10) unsigned | NO | PRI | NULL | auto_increment |
| category | varchar(64) | NO | UNI | NULL | |
+-------------+------------------+------+-----+---------+----------------+
2 rows in set (0.02 sec)
mysql> describe ing_title_categories;
+-------------------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------------+------------------+------+-----+---------+----------------+
| ID_Title_Category | int(10) unsigned | NO | PRI | NULL | auto_increment |
| ID_Title | int(10) unsigned | NO | MUL | NULL | |
| ID_Category | int(10) unsigned | NO | MUL | NULL | |
+-------------------+------------------+------+-----+---------+----------------+
3 rows in set (0.04 sec)
Let's say the data from the tables is:
mysql> select * from ing_titles;
+----------+-------------------+
| ID_Title | title |
+----------+-------------------+
| 3 | Chicken |
| 2 | corn |
| 1 | Fettucini Alfredo |
+----------+-------------------+
3 rows in set (0.00 sec)
mysql> select * from ing_categories;
+-------------+----------+
| ID_Category | category |
+-------------+----------+
| 1 | Dinner |
| 3 | Meat |
| 2 | Veggie |
+-------------+----------+
3 rows in set (0.00 sec)
I want to insert into ing_title_categories the record "corn, Veggie" or where ID_Title = 2 and ID_Category = 2.
Here's what I tried:
INSERT INTO ing_title_categories (ID_Title, ID_Category)
SELECT ing_titles.ID_Title, ing_categories.ID_Category
FROM ing_title_categories
LEFT JOIN ing_titles ON ing_title_categories.ID_Title=ing_titles.ID_Title
LEFT JOIN ing_categories ON ing_title_categories.ID_Category=ing_categories.ID_Category
WHERE (ing_titles.ID_Title=2) AND (ing_categories.ID_Category = 2);
There is no data inserted into the table ing_title_categories, and here is the reply from MySQL:
Query OK, 0 rows affected (0.00 sec)
Records: 0 Duplicates: 0 Warnings: 0
What is the correct syntax for inserting the ing_titles.ID_Title and ing_categories.ID_Category into the table ing_titles_categories?
Please, no PHP or Python examples. Use SQL that I can copy and paste into the MySQL prompt. I will be adding this to a C++ program, not PHP, JavaScript or Python.
Edit 1:
The ing_title_categories.ID_Title and ing_title_categories.ID_Category are foreign keys into the other tables.
INSERT INTO
ing_title_categories (ID_Title, ID_Category)
SELECT
ing_titles.ID_Title, ing_categories.ID_Category
FROM
ing_titles, ing_categories
WHERE
ing_titles.ID_Title = ing_categories.ID_Category AND
ing_titles.ID_Title = 2 AND ing_categories.ID_Category = 2;
SQL Fiddle demo
After taking advice from #DrewPierce and #KaiserM11, here is the MySQL sequence:
mysql> INSERT INTO ing_title_categories (ID_Title, ID_Category)
-> SELECT
-> ing_titles.ID_Title,
-> ing_categories.ID_Category
-> FROM ing_titles, ing_categories
-> where (ing_titles.ID_Title = 2) AND (ing_categories.ID_Category = 2)
-> ;
Query OK, 1 row affected (0.07 sec)
Records: 1 Duplicates: 0 Warnings: 0
mysql> select * from ing_title_categories;
+-------------------+----------+-------------+
| ID_Title_Category | ID_Title | ID_Category |
+-------------------+----------+-------------+
| 17 | 2 | 2 |
+-------------------+----------+-------------+
1 row in set (0.00 sec)
In this case, only possible way I see is using a UNION query like
INSERT INTO ing_title_categories (ID_Title, ID_Category)
SELECT Title, NULL
FROM ing_title WHERE ID_Title = 2
UNION
SELECT NULL, category
FROM ing_categories
WHERE ID_Category = 2
(OR)
You can change your table design and use an AFTER INSERT trigger to perform the same in one go.
EDIT:
If you can change your table design to something like below (No need of that extra chaining table)
ing_titles(ID_Title int not null auto_increment PK, title varchar(64) not null);
ing_categories( ID_Category int not null auto_increment PK,
category varchar(64) not null,
ing_titles_ID_Title int not null,
FOREIGN KEY (ing_titles_ID_Title)
REFERENCES ing_titles(ID_Title));
Then you can use a AFTER INSERT trigger and do the insertion like
DELIMITER //
CREATE TRIGGER ing_titles_after_insert
AFTER INSERT
ON ing_titles FOR EACH ROW
BEGIN
-- Insert record into ing_categories table
INSERT INTO ing_categories
( category,
ing_titles_ID_Title)
VALUES
('Meat' NEW.ID_Title);
END; //
DELIMITER ;
I am trying to select items in MySQL with consideration for case sensitivity, but I am having issues getting MySQL to perform any case distinction.
For example, all of the following statements
mysql> SELECT * FROM mytable WHERE name="alpha";
mysql> SELECT * FROM mytable WHERE name="ALPHA";
mysql> SELECT * FROM mytable WHERE name="aLpHa";
return the same results:
+----+-------+
| id | name |
+----+-------+
| 1 | alpha |
+----+-------+
1 row in set (0.00 sec)
I recognize that some character sets and collations in MySQL do not distinguish between case, and so changing the character set and collation from the default is a necessary step. I have tried changing and converting the table's character set and collate to utf8 and utf8_unicode_ci respectively, but I am uncertain if it worked correctly.
mysql> SHOW TABLE STATUS;
+---------+--------+---------+------------+-------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+-------------+------------+-----------------+----------+----------------+---------+
| Name | Engine | Version | Row_format | Rows | Avg_row_length | Data_length | Max_data_length | Index_length | Data_free | Auto_increment | Create_time | Update_time | Check_time | Collation | Checksum | Create_options | Comment |
+---------+--------+---------+------------+-------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+-------------+------------+-----------------+----------+----------------+---------+
| mytable | InnoDB | 10 | Compact | 68886 | 83 | 5783552 | 0 | 7372800 | 17825792 | 67039 | 2014-08-02 15:05:07 | NULL | NULL | utf8_unicode_ci | NULL | | |
+---------+--------+---------+------------+-------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+-------------+------------+-----------------+----------+----------------+---------+
1 row in set (0.04 sec)
mysql> SHOW FULL COLUMNS FROM mytable;
+-------+-------------+-----------------+------+-----+---------+----------------+---------------------------------+---------+
| Field | Type | Collation | Null | Key | Default | Extra | Privileges | Comment |
+-------+-------------+-----------------+------+-----+---------+----------------+---------------------------------+---------+
| id | int(11) | NULL | NO | PRI | NULL | auto_increment | select,insert,update,references | |
| name | varchar(10) | utf8_unicode_ci | NO | | NULL | | select,insert,update,references | |
+-------+-------------+-----------------+------+-----+---------+----------------+---------------------------------+---------+
2 rows in set (0.01 sec)
As you can see from above, the collation of the table has now been changed to utf8_unicode_ci and the collation of the relevant column has been changed as well.
Is there any additional step I need to perform so that MySQL will make a distinction with respect to character case? I am using MySQL Server version: 5.5.37-0ubuntu0.13.10.1 (Ubuntu).
Note that I cannot simply use queries with the BINARY keyword, such as:
SELECT * FROM mytable WHERE BINARY name="alpha";
because I am actually just using MySQL through Django's ORM, which does not support this type of lookup as far as I know. Thank you in advance for your help!
You can use option:
COLLATE utf8_bin
Example:
http://sqlfiddle.com/#!2/60d73/1/0
vs.
http://sqlfiddle.com/#!2/60d73/2/0
You can alter your table using:
alter table mytable ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE utf8_bin;