Som det står på manualsidan
, ALTER TABLE
kräver att alla nya typattribut definieras.
Det finns dock ett sätt att övervinna detta. Du kan använda INFORMATION_SCHEMA
metadata
för att rekonstruera önskad ALTER
fråga. till exempel, om vi har en enkel tabell:
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)
då kan vi återskapa vår alter-sats med:
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'
resultatet skulle bli:
+--------------------------------------+ | s | +--------------------------------------+ | id @new_type NOT NULL auto_increment | | value @new_type NOT NULL | +--------------------------------------+
Här har jag lämnat @new_type
för att indikera att vi kan använda variabel för det (eller till och med ersätta vår nya typ direkt för att fråga). Med variabel skulle det vara:
-
Ställ in våra variabler.
mysql> SET @new_type := 'VARCHAR(10)', @column_name := 'value'; Query OK, 0 rows affected (0.00 sec)
-
Förbered variabel för förberedd uttalande (det är en lång fråga, men jag har lämnat förklaringar ovan):
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);
-
Förbered uttalande:
mysql> prepare stmt from @sql; Query OK, 0 rows affected (0.00 sec) Statement prepared
-
Slutligen, kör det:
mysql> execute stmt; Query OK, 0 rows affected (0.22 sec) Records: 0 Duplicates: 0 Warnings: 0
Sedan kommer vi att ändra vår datatyp till VARCHAR(10)
med att spara alla övriga specifikationer:
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)