Como se indica en la página del manual
, ALTER TABLE
requiere que se definan todos los atributos de tipo nuevos.
Sin embargo, hay una manera de superar esto. Puede usar INFORMATION_SCHEMA
metadatos
para reconstruir el ALTER
deseado consulta. por ejemplo, si tenemos una tabla simple:
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)
entonces podemos reproducir nuestra declaración alter con:
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'
el resultado seria:
+--------------------------------------+ | s | +--------------------------------------+ | id @new_type NOT NULL auto_increment | | value @new_type NOT NULL | +--------------------------------------+
Aquí he dejado @new_type
para indicar que podemos usar variable para eso (o incluso sustituir nuestro nuevo tipo directamente para consultar). Con variable sería:
-
Establecer nuestras variables.
mysql> SET @new_type := 'VARCHAR(10)', @column_name := 'value'; Query OK, 0 rows affected (0.00 sec)
-
Preparar variable para declaración preparada (es una consulta larga, pero he dejado explicaciones arriba):
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);
-
Preparar declaración:
mysql> prepare stmt from @sql; Query OK, 0 rows affected (0.00 sec) Statement prepared
-
Finalmente, ejecútelo:
mysql> execute stmt; Query OK, 0 rows affected (0.22 sec) Records: 0 Duplicates: 0 Warnings: 0
Luego cambiaremos nuestro tipo de datos a VARCHAR(10)
con guardar todos los demás especificadores:
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)