Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Zmień typ danych kolumny w MySQL bez utraty innych metadanych (DEFAULT, NOTNULL...)

Jak podano na stronie podręcznika , ALTER TABLE wymaga zdefiniowania wszystkich nowych atrybutów typu.

Istnieje jednak sposób na przezwyciężenie tego. Możesz użyć INFORMATION_SCHEMA metadane zrekonstruować żądany ALTER zapytanie. na przykład, jeśli mamy prostą tabelę:

mysql> DESCRIBE t;
+-------+------------------+------+-----+---------+----------------+
| Field | Type             | Null | Key | Default | Extra          |
+-------+------------------+------+-----+---------+----------------+
| id    | int(11) unsigned | NO   | PRI | NULL    | auto_increment |
| value | varchar(255)     | NO   |     | NULL    |                |
+-------+------------------+------+-----+---------+----------------+
2 rows in set (0.01 sec)

następnie możemy odtworzyć nasze oświadczenie alter za pomocą:

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'

wynik byłby następujący:

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

Tutaj zostawiłem @new_type aby wskazać, że możemy do tego użyć zmiennej (lub nawet zastąpić nasz nowy typ bezpośrednio zapytaniem). Ze zmienną, która byłaby:

  • Ustaw nasze zmienne.

    mysql> SET @new_type := 'VARCHAR(10)', @column_name := 'value';
    Query OK, 0 rows affected (0.00 sec)
    
  • Przygotuj zmienną dla przygotowanej instrukcji (to długie zapytanie, ale powyżej zostawiłem wyjaśnienia):

    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);
    
  • Przygotuj oświadczenie:

    mysql> prepare stmt from @sql;
    Query OK, 0 rows affected (0.00 sec)
    Statement prepared
    
  • Na koniec wykonaj to:

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

Następnie zmienimy typ danych na VARCHAR(10) z zachowaniem wszystkich pozostałych specyfikatorów:

mysql> DESCRIBE t;
+-------+------------------+------+-----+---------+----------------+
| Field | Type             | Null | Key | Default | Extra          |
+-------+------------------+------+-----+---------+----------------+
| id    | int(11) unsigned | NO   | PRI | NULL    | auto_increment |
| value | varchar(10)      | NO   |     | NULL    |                |
+-------+------------------+------+-----+---------+----------------+
2 rows in set (0.00 sec)


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Umieść wyniki zapytania wiersza poleceń mysql w zmiennej skryptu bash

  2. Przekazywanie tablicy przez AJAX z php do javascript

  3. Symfony2:czy fetch=EAGER tworzy sprzężenie?

  4. Uzyskaj wartość MAX z jednej kolumny i MIN z innej kolumny

  5. Problem z dopasowaniem MySQL