Modifica set di caratteri e regole di confronto in tutte le colonne in tutte le tabelle in MySQL


18

Devo eseguire queste istruzioni in tutte le tabelle per tutte le colonne.

alter table table_name charset=utf8;
alter table table_name alter column column_name charset=utf8;

È possibile automatizzarlo in qualche modo all'interno di MySQL? Preferirei evitare mysqldump

Aggiornamento: Richard Bronosky mi ha mostrato la strada :-)

La query che dovevo eseguire in ogni tabella:

alter table DBname.DBfield CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;

Query folle per generare tutte le altre query:

SELECT distinct CONCAT( 'alter table ', TABLE_SCHEMA, '.', TABLE_NAME, '  CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;' ) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = 'DBname';

Volevo solo eseguirlo in un database. Stava impiegando troppo tempo per eseguire tutto in un unico passaggio. Si è scoperto che stava generando una query per campo per tabella. Era necessaria solo una query per tabella (distinta per il salvataggio). Ottenere l'output su un file è stato come me ne sono reso conto.

Come generare l'output in un file:

mysql -B -N --user=user --password=secret -e "SELECT distinct CONCAT( 'alter table ', TABLE_SCHEMA, '.', TABLE_NAME, '  CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;' ) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = 'DBname';" > alter.sql

E infine per eseguire tutte le query:

mysql --user=user --password=secret < alter.sql

Grazie Richard. Tu sei l'uomo!

Risposte:


16

Prima di tutto, non limitarti a crederci sulla parola! Metti alla prova il mio suggerimento con questo:

select CONCAT('alter table ',TABLE_SCHEMA,'.',TABLE_NAME,' charset=utf8;') from information_schema.TABLES WHERE TABLE_SCHEMA != 'information_schema' limit 10; select CONCAT('alter table ',TABLE_SCHEMA,'.',TABLE_NAME,' alter column ',COLUMN_NAME,' charset=utf8;') from information_schema.COLUMNS WHERE TABLE_SCHEMA != 'information_schema' limit 10;

Se ti senti bene con il risultato di ciò, rimuovi le clausole limitate e salva l'output in uno script SQL o, diventa elaborato e reindirizza l'output direttamente a mysql in modo simile a quello che ho illustrato qui . Sarebbe così:

mysql -B -N --host=prod-db1 --user=admin --password=secret -e "select CONCAT('alter table ',TABLE_SCHEMA,'.',TABLE_NAME,' charset=utf8;') from information_schema.TABLES WHERE TABLE_SCHEMA != 'information_schema'; select CONCAT('alter table ',TABLE_SCHEMA,'.',TABLE_NAME,' alter column ',COLUMN_NAME,' charset=utf8;') from information_schema.COLUMNS WHERE TABLE_SCHEMA != 'information_schema';" | mysql --host=prod-db1 --user=admin --password=secret

Quando inizi a pensare di utilizzare un SQL valido per generare un SQL valido, cambia l'intero gioco. Rimarrai stupito da quanti usi trovi per questo.


Quasi lì! Ma non riesco a capire bene la sintassi
The Disintegrator,

ok ce l'ho. Sto aggiungendo la sintassi corretta alla risposta. La tua idea governa
The Disintegrator,

4

In realtà, è possibile utilizzare CONVERT TO in una tabella per convertire tutte le colonne all'interno di tale tabella nel set di caratteri e nelle regole di confronto.

SELECT CONCAT('ALTER TABLE ',TABLE_SCHEMA,'.',TABLE_NAME,' CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;') FROM information_schema.TABLES WHERE TABLE_SCHEMA = 'databasename';

Inoltre, ha più senso per me selezionare il database effettivo su cui si desidera farlo. Così questo:

... WHERE TABLE_SCHEMA = 'databasename';

piuttosto che questo:

... WHERE TABLE_SCHEMA != 'information_schema';

Ma immagino che se davvero volessi farlo su tutti i tavoli, potresti usare il primo. Però mi sembra un po 'pesante. :)


1

Per cambiare le regole di confronto su tutte le colonne che ho usato

SELECT CONCAT(  'ALTER TABLE ',  `TABLE_NAME` ,  ' CHANGE `',  `COLUMN_NAME` ,  '` `',`COLUMN_NAME` ,  '` ',  `DATA_TYPE` ,  '(',  `CHARACTER_MAXIMUM_LENGTH` ,  ') CHARACTER SET utf8 COLLATE utf8_swedish_ci ;' ) FROM  `COLUMNS` WHERE  `TABLE_SCHEMA` =  <schema> AND  `COLLATION_NAME` !=  'utf8_swedish_ci' ORDER BY  `TABLE_NAME` ,  `ORDINAL_POSITION` ;

0

È possibile utilizzare il information_schemadatabase per trovare la colonna e la tabella che è necessario modificare. Puoi trovarli con:

SELECT table_name, column_name FROM information_schema.`COLUMNS`
WHERE table_schema='your database' AND collation_name LIKE 'latin%';

Quindi è possibile automatizzare l'alterazione con uno script SQL, una procedura di archiviazione o con il linguaggio di sviluppo preferito.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.