I believe there is not a native command that does everything, it is possible to create a query that does the work in its place.
Tables
Generating the necessary queries for each table:
SELECT CONCAT(
"ALTER TABLE ",
TABLE_NAME,
" CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;")
FROM INFORMATION_SCHEMA.TABLES T
WHERE TABLE_TYPE="BASE TABLE"
AND TABLE_SCHEMA like '<schema>'
AND DATA_TYPE in ('varchar', 'text')
Now just copy and paste. Note the filter by DATA_TYPE
to select only fields that have a collaction.
Databases
In the case of databases, I arrived at the following command:
SELECT CONCAT(
"ALTER DATABASE ",
schema_name,
" CHARACTER SET utf8 COLLATE utf8_general_ci;")
FROM information_schema.schemata
WHERE schema_name LIKE '%'
To automate the process you will need to create a precedent or script and run each command with EXECUTE
.
A Procedure model to be used as a base can be found here.
** Update **
With the information already available above and with the dynamic queries execution documentation, I set up the procedure below to make the automatic conversion of databases and their respective tables:
CREATE PROCEDURE change_collation()
BEGIN
DECLARE db VARCHAR(255);
DECLARE tab VARCHAR(255);
DECLARE done INT DEFAULT 0;
DECLARE done2 INT DEFAULT 0;
DECLARE databasesCursor CURSOR FOR
SELECT schema_name
FROM information_schema.schemata
WHERE schema_name LIKE '%';
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
OPEN databasesCursor;
REPEAT
FETCH databasesCursor INTO db;
IF NOT done THEN
SET @q = CONCAT(
"ALTER DATABASE ",
db,
" CHARACTER SET utf8 COLLATE utf8_general_ci");
PREPARE stmt1 FROM @q;
EXECUTE stmt1;
DEALLOCATE PREPARE stmt1;
innerblock: BEGIN
DECLARE tablesCursor CURSOR FOR
SELECT TABLE_NAME
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_TYPE = "BASE TABLE"
AND TABLE_SCHEMA = db
AND DATA_TYPE in ('varchar', 'text');
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done2 = TRUE;
OPEN tablesCursor;
REPEAT
FETCH tablesCursor INTO tab;
IF NOT done2 THEN
SET @q = CONCAT(
"ALTER TABLE ",
db, ".", tab,
" CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci");
PREPARE stmt1 FROM @q;
EXECUTE stmt1;
DEALLOCATE PREPARE stmt1;
END IF;
UNTIL done2 END REPEAT;
CLOSE tablesCursor;
END;
END IF;
UNTIL tablesCursor END REPEAT;
CLOSE databasesCursor;
END//
To execute the Procedure, just call it that:
call change_collation();
Observing: I could not properly test the above procedure because in Sqlfiddle there is an error. Obviously they would not allow such commands on the server.
Final considerations
To Procedure presented in this solution will list the databases and their tables, applying the change command in each one. Note, however, that there is no exceptional treatment, so if there is any problem, for example related to the lack of permission, the execution will be stopped.
It is important to always consider the permissions used to execute both the Procedure as the executed commands.
Try generating a script from the Information Schema with the command for each of the database tables.
– user4552
I have this script in SQL Server... a shame!
– utluiz
@utluiz Will it be so different from SQL Server for Mysql? I have idea that the adaptation is superficial, but I’m not expert in SQL Server!
– Zuul
It’s not that different. I made a simplified version.
– utluiz