Come modificare le regole di confronto di database, tabella, colonna?


Risposte:


257

Devi convertire ciascuna tabella singolarmente:

ALTER TABLE mytable CONVERT TO CHARACTER SET utf8mb4 

(questo convertirà anche le colonne), o esporterà il database con latin1e lo importerà nuovamente utf8mb4.


15
Ma voglio cambiare le regole di confronto delle colonne. Questo cambierà solo le regole di confronto della tabella.
user158469

7
@rsensan: CONVERTcambierà anche le regole di confronto delle colonne.
Quassnoi,

21
database SET DI CARATTERI DEFAULT ALTER SCHEMA utf8 DEFAULT COLLATE utf8_general_ci;
Stormwild,

8
@stormwild: questo non influirà sulle tabelle esistenti
Quassnoi,

47
La mia domanda: ALTER TABLE MYTABLECONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; Per favore, non usare più utf8_general_ci ;-)
Kapitein Witbaard,

210

Sto contribuendo qui, come ha chiesto l'OP:

Come modificare le regole di confronto di database, tabella, colonna?

La risposta selezionata la indica semplicemente a livello di tabella.


Modificandolo a livello di database:

ALTER DATABASE <database_name> CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

Modificandolo per tabella:

ALTER TABLE <table_name> CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

La buona pratica è di cambiarlo a livello di tabella poiché lo cambierà anche per le colonne. La modifica per una colonna specifica è per ogni caso specifico.

Modifica delle regole di confronto per una colonna specifica:

ALTER TABLE <table_name> MODIFY <column_name> VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

15
Questo in realtà risponde direttamente alla domanda. Ne avevo bisogno, poiché le mie modifiche a livello di tabella NON stavano aggiornando le colonne. Lo esaminerò più tardi; ma questa è l'informazione che mi ha fatto superare i momenti difficili. Grazie.
Parapluie,

9
La migliore risposta per questo.
jubi4dition,

Sì, è necessario specificare il tipo di colonna. Ecco un comando magico per ottenere tutti i tipi. Utilizzando la modifica multilinea è possibile generare il comando per aggiornare tutte le colonne contemporaneamente iniziando da qui:SELECT table_schema , table_name , column_name , COLLATION_NAME , COLUMN_TYPE FROM information_schema.columns WHERE collation_name != 'utf8_general_ci' AND table_schema not in ('information_schema','mysql', 'performance_schema','sys');
William Entriken,

Per una singola colonna puoi semplicemente fare: ALTER TABLE nome_tabella CAMBIA nome_colonna VARCHAR (45) COLLATE utf8mb4_bin;
TomoMiha,

68

Puoi eseguire uno script php.

               <?php
                   $con = mysql_connect('localhost','user','password');
                   if(!$con) { echo "Cannot connect to the database ";die();}
                   mysql_select_db('dbname');
                   $result=mysql_query('show tables');
                   while($tables = mysql_fetch_array($result)) {
                            foreach ($tables as $key => $value) {
                             mysql_query("ALTER TABLE $value CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci");
                       }}
                   echo "The collation of your database has been successfully changed!";
                ?>

43

Per modificare le regole di confronto per le tabelle singolarmente puoi utilizzare,

ALTER TABLE mytable CONVERT TO CHARACTER SET utf8

Per impostare regole di confronto predefinite per l'intero database,

ALTER DATABASE  `databasename` DEFAULT CHARACTER SET utf8 COLLATE utf8_bin

o altro,

Vai a PhpMyAdmin-> Operazioni-> Fascicolazione.

Lì troverai la casella di selezione che contiene tutte le regole di confronto esistenti. In modo che qui puoi cambiare le tue regole di confronto. Quindi qui dopo la tabella del database seguirà queste regole di confronto durante la creazione di una nuova colonna. Non è necessario selezionare le regole di confronto durante la creazione di nuove colonne.


Grazie mille, questo è stato utile
JoZ3

15

La query seguente genererà query ALTER che modificano le regole di confronto per tutte le colonne appropriate in tutte le tabelle in un determinato tipo (utf8_general_ci nel mio esempio di seguito).

SELECT concat
        (
            'ALTER TABLE ', 
                t1.TABLE_SCHEMA, 
                '.', 
                t1.table_name, 
                ' MODIFY ', 
                t1.column_name, 
                ' ', 
                t1.data_type, 
                '(' , 
                    CHARACTER_MAXIMUM_LENGTH, 
                ')', 
                ' CHARACTER SET utf8 COLLATE utf8_general_ci;'
        )
from 
    information_schema.columns t1
where 
    t1.TABLE_SCHEMA like 'you_db_name_goes_here' AND
    t1.COLLATION_NAME IS NOT NULL AND
    t1.COLLATION_NAME NOT IN ('utf8_general_ci');

+1 Mi piace di più questa risposta. Non tutti hanno PHP magicamente da qualche parte. Alcuni utenti usano altre lingue con MySQL. È stato facile eseguirlo in MySQL Workbench, copiare le righe e incollare. Ho appena fatto il passo extra per eseguire quanto sopra information_schema.tablese il codice in concatALTER TABLE 'schema'.'table' CHARACTER SET = utf8mb4 , COLLATE = utf8mb4_bin ;
Pierre

1
Questo
errore risolve i

11

Se si esegue phpMyAdmin >> selezionare il database >> selezionare la tabella >> andare alla scheda "Operazioni" >> nella sezione "Opzioni tabella" >> è possibile selezionare Fascicolazione dall'elenco a discesa >> e una volta premuto {Vai} nel nella parte superiore dello schermo verrà visualizzato un messaggio:

La tua query SQL è stata eseguita correttamente

e una sceneggiatura

ALTER TABLE `tableName` CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci 

Ma NON cambierà le regole di confronto delle colonne esistenti. Per fare ciò puoi usare questo script (anche questo è arrivato da phpMyAdmin)

ALTER TABLE  `tableName` CHANGE  `Name`  `Name` VARCHAR( 255 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL


5

Basta eseguire questo SQL per convertire contemporaneamente tutte le tabelle del database. Cambia COLLEZIONE e databaseName in base alle tue esigenze.

SELECT CONCAT("ALTER TABLE ", TABLE_SCHEMA, '.', TABLE_NAME," COLLATE utf8_general_ci;") AS    ExecuteTheString
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA="databaseName"
AND TABLE_TYPE="BASE TABLE";

4

È possibile modificare il CHARSET e la COLLATION di tutte le tabelle tramite lo script PHP come segue. Mi piace la risposta di hkasera, ma il problema è che la query viene eseguita due volte su ogni tabella. Questo codice è quasi lo stesso ad eccezione dell'utilizzo di MySqli invece di mysql e della prevenzione di doppie query. Se potessi votare, avrei votato la risposta di hkasera.

<?php
$conn1=new MySQLi("localhost","user","password","database");
if($conn1->connect_errno){
    echo mysqli_connect_error();
    exit;
}
$res=$conn1->query("show tables") or die($conn1->error);
while($tables=$res->fetch_array()){
    $conn1->query("ALTER TABLE $tables[0] CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci") or die($conn1->error);
}
echo "The collation of your database has been successfully changed!";

$res->free();
$conn1->close();

?>

Questo ha funzionato per me perfettamente, dopo l'aggiornamento a Zabbix 5. Solo per dire che ho cambiato il Set di caratteri e regole di confronto come questo: CONVERT TO CHARACTER SET utf8 COLLATE utf8_bin.
robe007,

4

Puoi semplicemente aggiungere questo codice al file di script

//Database Connection
$host = 'localhost';
$db_name = 'your_database_name';
$db_user =  'your_database_user_name';
$db_pass = 'your_database_user_password';

$con = mysql_connect($host,$db_user,$db_pass);

if(!$con) { echo "Cannot connect to the database ";die();}

  mysql_select_db($db_name);

  $result=mysql_query('show tables');

  while($tables = mysql_fetch_array($result)) {
    foreach ($tables as $key => $value) {
    mysql_query("ALTER TABLE $value CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci");
  }
}

echo "The collation of your database has been successfully changed!";

4

Sono stato sorpreso di apprendere, e quindi ho dovuto tornare qui e riferire, che l'eccellente e ben mantenuto script Interconnect / it SAFE SEARCH E REPLACE ON DATABASE ha alcune opzioni per convertire le tabelle in utf8 / unicode e persino convertire in innodb . È uno script comunemente utilizzato per migrare un sito Web basato su database (Wordpress, Drupal, Joomla, ecc.) Da un dominio a un altro.

pulsanti di script di interconnessione


3

L'ho letto qui, che è necessario convertire manualmente ogni tabella, non è vero. Ecco una soluzione su come farlo con una procedura memorizzata:

DELIMITER $$

DROP PROCEDURE IF EXISTS changeCollation$$

-- character_set parameter could be 'utf8'
-- or 'latin1' or any other valid character set
CREATE PROCEDURE changeCollation(IN character_set VARCHAR(255))
BEGIN
DECLARE v_finished INTEGER DEFAULT 0;
DECLARE v_table_name varchar(255) DEFAULT "";
DECLARE v_message varchar(4000) DEFAULT "No records";

-- This will create a cursor that selects each table,
-- where the character set is not the one
-- that is defined in the parameter

DECLARE alter_cursor CURSOR FOR SELECT DISTINCT TABLE_NAME
FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = DATABASE()
AND COLLATION_NAME NOT LIKE CONCAT(character_set, '_%');

-- This handler will set the value v_finished to 1
-- if there are no more rows

DECLARE CONTINUE HANDLER
FOR NOT FOUND SET v_finished = 1;

OPEN alter_cursor;

-- Start a loop to fetch each rows from the cursor
get_table: LOOP

-- Fetch the table names one by one
FETCH alter_cursor INTO v_table_name;

-- If there is no more record, then we have to skip
-- the commands inside the loop
IF v_finished = 1 THEN
LEAVE get_table;
END IF;

IF v_table_name != '' THEN

IF v_message = 'No records' THEN
SET v_message = '';
END IF;

-- This technic makes the trick, it prepares a statement
-- that is based on the v_table_name parameter and it means
-- that this one is different by each iteration inside the loop

SET @s = CONCAT('ALTER TABLE ',v_table_name,
' CONVERT TO CHARACTER SET ', character_set);
PREPARE stmt FROM @s;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

SET v_message = CONCAT('The table ', v_table_name ,
' was changed to the default collation of ', character_set,
'.\n', v_message);

SET v_table_name = '';

END IF;
-- Close the loop and the cursor
END LOOP get_table;
CLOSE alter_cursor;

-- Returns information about the altered tables or 'No records'
SELECT v_message;

END $$

DELIMITER ;

Dopo aver creato la procedura, chiamala semplicemente:

CALL changeCollation('utf8');

Per maggiori dettagli leggi questo blog .


2

se si desidera aggiornare il set di caratteri predefinito su uno schema:

 ALTER SCHEMA MYSCHEMA DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_unicode_ci;

1

Ho usato il seguente script di shell. Prende il nome del database come parametro e converte tutte le tabelle in un altro set di caratteri e regole di confronto (fornite da altri parametri o valore predefinito definito nello script).

#!/bin/bash

# mycollate.sh <database> [<charset> <collation>]
# changes MySQL/MariaDB charset and collation for one database - all tables and
# all columns in all tables

DB="$1"
CHARSET="$2"
COLL="$3"

[ -n "$DB" ] || exit 1
[ -n "$CHARSET" ] || CHARSET="utf8mb4"
[ -n "$COLL" ] || COLL="utf8mb4_general_ci"

echo $DB
echo "ALTER DATABASE $DB CHARACTER SET $CHARSET COLLATE $COLL;" | mysql

echo "USE $DB; SHOW TABLES;" | mysql -s | (
    while read TABLE; do
        echo $DB.$TABLE
        echo "ALTER TABLE $TABLE CONVERT TO CHARACTER SET $CHARSET COLLATE $COLL;" | mysql $DB
    done
)

1

La mia soluzione è una combinazione di @Dzintars e @Quassnoi Answer.

SELECT CONCAT("ALTER TABLE ", TABLE_SCHEMA, '.', TABLE_NAME," CONVERT TO CHARACTER SET utf8mb4 ;") AS    ExecuteTheString
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA="<your-database>"
AND TABLE_TYPE="BASE TABLE";

Usando CONVERT TO, questo genera uno script, che converte tutte le tabelle <your-database>nella codifica richiesta. Questo cambia anche la codifica di ogni colonna !


1

Migliore variante per generare script SQL su richiesta SQL. Non rovinerà i valori predefiniti / null.

SELECT concat
    (
        'ALTER TABLE ', 
            t1.TABLE_SCHEMA, 
            '.', 
            t1.table_name, 
            ' MODIFY ', 
            t1.column_name, 
            ' ', 
            t1.column_type,
            ' CHARACTER SET utf8 COLLATE utf8_general_ci',
            if(t1.is_nullable='YES', ' NULL', ' NOT NULL'),
            if(t1.column_default is not null, concat(' DEFAULT \'', t1.column_default, '\''), ''),
            ';'
    )
from 
    information_schema.columns t1
where 
    t1.TABLE_SCHEMA like 'your_table_here' AND
    t1.COLLATION_NAME IS NOT NULL AND
    t1.COLLATION_NAME NOT IN ('utf8_general_ci');

0

Modo rapido: esporta in file SQL, usa la ricerca e sostituisci per cambiare il testo che devi cambiare. Creare un nuovo database, importare i dati e quindi rinominare il vecchio database e quello nuovo con il vecchio nome.


0

Per modificare le regole di confronto di tutti i campi in tutte le tabelle di un database contemporaneamente:

Stavo solo aggiungendo un altro loop per i campi all'interno delle tabelle alla soluzione tramite Php prima menzionato. Questo ha aiutato, anche tutti i campi nelle tabelle vengono convertiti.

<?php
$con = mysql_connect('localhost','user','pw');
if(!$con) { echo "Cannot connect to the database ";die();}
mysql_select_db('database_name');
$result=mysql_query('show tables');
while($tables = mysql_fetch_array($result)) {

foreach ($tables as $key => $table) {                   // for each table

    $sql = "ALTER TABLE $table CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci";
    echo "\n".$sql;
    mysql_query($sql);

    $sql = "show fields in ".$table." where type like 'varchar%' or type like 'char%' or type='text' or type='mediumtext';";
    $rs2=mysql_query($sql);
    while( $rw2 = mysql_fetch_array($rs2) ){            // for each field in table

        $sql = "ALTER TABLE `".$table."` CHANGE `".$rw2['Field']."` `".$rw2['Field']."` ".$rw2['Type']." CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL;";
        echo "\n".$sql;
        mysql_query($sql);

    } 


}
}
echo "The collation of your database has been successfully changed!";

?>}

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.