Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Spaltendatentyp in MySQL ändern, ohne andere Metadaten zu verlieren (DEFAULT, NOTNULL ...)

Wie es in der Manual Page angegeben ist , ALTER TABLE erfordert, dass alle neuen Typattribute definiert werden.

Es gibt jedoch eine Möglichkeit, dies zu überwinden. Sie können INFORMATION_SCHEMA verwenden Metadaten gewünschten ALTER zu rekonstruieren Anfrage. zum Beispiel, wenn wir eine einfache Tabelle haben:

mysql> DESCRIBE t;+-------+------------------+------+-----+- --------+----------------+| Feld | Geben Sie | ein Null | Schlüssel | Standard | Extra |+-------+------------------+------+-----+------- --+----------------+| ID | int(11) ohne Vorzeichen | NEIN | PRI | NULL | auto_inkrement || Wert | varchar(255) | NEIN | | NULL | |+-------+------------------+------+-----+-------- -+----------------+2 Zeilen im Satz (0,01 Sek.)

dann können wir unsere alter-Anweisung reproduzieren mit:

SELECT 
  CONCAT(
    COLUMN_NAME, 
    ' @new_type', 
    IF(IS_NULLABLE='NO', ' NOT NULL ', ' '), 
    EXTRA
  ) AS s
FROM 
  INFORMATION_SCHEMA.COLUMNS 
WHERE 
  TABLE_SCHEMA='test' 
  AND 
  TABLE_NAME='t'
 

das Ergebnis wäre:

+--------------------------------------+| s |+--------------------------------------------------+| id @new_type NOT NULL auto_increment || value @new_type NOT NULL |+------------------------------------+

Hier habe ich @new_type hinterlassen um anzuzeigen, dass wir dafür eine Variable verwenden können (oder sogar unseren neuen Typ direkt für die Abfrage ersetzen können). Mit Variable wäre das:

  • Setzen Sie unsere Variablen.

    mysql> SET @new_type := 'VARCHAR(10)', @column_name := 'value';
    Query OK, 0 rows affected (0.00 sec)
     
  • Variable für vorbereitete Anweisung vorbereiten (Es ist eine lange Abfrage, aber ich habe oben Erklärungen hinterlassen):

    SET @sql = (SELECT CONCAT('ALTER TABLE t CHANGE `',COLUMN_NAME, '` `', COLUMN_NAME, '` ', @new_type, IF(IS_NULLABLE='NO', ' NOT NULL ', ' '), EXTRA) AS s FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA='test' AND TABLE_NAME='t' AND [email protected]_name);
     
  • Anweisung vorbereiten:

    mysql> prepare stmt from @sql;
    Query OK, 0 rows affected (0.00 sec)
    Statement prepared
     
  • Führen Sie es schließlich aus:

    mysql> execute stmt;
    Query OK, 0 rows affected (0.22 sec)
    Records: 0  Duplicates: 0  Warnings: 0
     

Dann ändern wir unseren Datentyp in VARCHAR(10) mit dem Speichern aller restlichen Spezifizierer:

mysql> DESCRIBE t;+-------+------------------+------+-----+- --------+----------------+| Feld | Geben Sie | ein Null | Schlüssel | Standard | Extra |+-------+------------------+------+-----+------- --+----------------+| ID | int(11) ohne Vorzeichen | NEIN | PRI | NULL | auto_inkrement || Wert | varchar(10) | NEIN | | NULL | |+-------+------------------+------+-----+-------- -+----------------+2 Zeilen im Satz (0,00 Sek.)