2014-04-07 19 views
10

Se lo faccio:Cambia il tipo di dati della colonna in MySQL senza perdere altri metadati (DEFAULT, notnull ...)

ALTER TABLE testtable MODIFY mycolumn NEWDATATYPE; 

perdo altre definizioni come, i commenti, i valori di default non NULL ... C'è un modo di farlo?

In PostgreSQL I used:

ALTER TABLE testtable ALTER COLUMN mycolumn NEWDATATYPE; 

E lo fa ciò che si suppone: cambiare il tipo di dati della colonna, senza toccare qualsiasi altra definizione, solo dando errore se i tipi di dati non erano compatibili e così via (ma è possibile specificare UTILIZZO).

Proverò una soluzione alternativa, ma ho effettuato una query per identificare più colonne tra tabelle diverse per aggiornare il tipo di dati e ora ho identificato che questi dati sono stati persi, quindi dovrò rifarlo considerando queste informazioni pure.

+0

ho avuto che [Modifica richiede] (http://dev.mysql.com/doc/refman /5.1/en/alter-table.html) tutte le _column_definition_, penso che potrebbe avere un'altra sintassi per cambiare solo quello che vuoi. –

risposta

4

Come indicato in manual page, ALTER TABLE richiede la definizione di tutti i nuovi attributi di tipo.

Tuttavia, c'è un modo per superare questo. È possibile utilizzare INFORMATION_SCHEMA meta-data per ricostruire la query ALTER desiderata. per esempio, se abbiamo semplice tabella:

 
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) 

poi siamo in grado di riprodurre la nostra dichiarazione 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' 

il risultato sarebbe:

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

Qui ho lasciato @new_type per indicare che possiamo usare una variabile per questo (o addirittura sostituire il nostro nuovo tipo direttamente alla query).Con variabile che sarebbe:

  • Impostare le nostre variabili.

    mysql> SET @new_type := 'VARCHAR(10)', @column_name := 'value'; 
    Query OK, 0 rows affected (0.00 sec) 
    
  • Preparare variabile per prepared statement (è lunga query, ma ho lasciato spiegazioni sopra):

    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); 
    
  • Preparare dichiarazione:

    mysql> prepare stmt from @sql; 
    Query OK, 0 rows affected (0.00 sec) 
    Statement prepared 
    
  • Infine, eseguirlo:

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

Poi avremo il nostro tipo di dati cambiato VARCHAR(10) con il salvataggio di tutti i prescrittori di riposo:

 
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) 
+0

Ottimo consiglio. Non è facile da ricordare, ma semplifica quando si hanno almeno 100 colonne da aggiornare. Come un vantaggio, sarebbe bello se si potesse aggiungere COMMENTO e DEFAULT alla propria clausola, come tutto dovrebbe essere mantenuto, come: 'SE (COLUMN_DEFAULT NON È NULL, CONCAT ('DEFAULT', QUOTE (c.COLUMN_DEFAULT), ''), ''), IF (COLUMN_COMMENT NON È NULL E COLUMN_COMMENT! = '', CONCAT ('COMMENT', QUOTE (c.COLUMN_COMMENT), ''), ''), '. Questo completerebbe la risposta. –

+0

Sì, dovrebbe essere aggiunto per un caso comune - quindi il mio punto era mostrare tutta l'idea –

0
ALTER TABLE tableName 
MODIFY COLUMN columnName datatype 
+0

Questo dà il problema che mi ha portato a questa domanda. –

0

Quando si utilizza CHANGE o MODIFY in ALTER table_name, column_definition deve includere il tipo di dati e tutti gli attributi che dovrebbero applicare alla nuova colonna, diverso da attributi indice come PRIMARY KEY o UNIQUE. Gli attributi presenti nella definizione originale ma non specificati per la nuova definizione non vengono inoltrati.

Supponiamo che una colonna col1 è definito come INT UNSIGNED DEFAULT 1COMMENT 'my column' e modificare la colonna come segue:

ALTER TABLE t1 MODIFY col1 BIGINT; 

La colonna risultante verrà definito come BIGINT, ma non includerà gli attributi UNSIGNED DEFAULT 1COMMENT 'my column'. Per mantenere loro, la dichiarazione deve essere:

ALTER TABLE t1 MODIFY col1 BIGINT UNSIGNED DEFAULT 1 COMMENT 'my column'; 

Quando si modifica un tipo di dati utilizzando CHANGE o MODIFY, MySQL cerca di convertire i valori delle colonne esistenti al nuovo tipo nel miglior modo possibile.

Vedere documentation.

+0

Ho visto i documenti e mi aspettavo che ci fosse un modo per cambiare solo quello che volevi. Modo brutto per cambiare solo informazioni di precisione. Ho capito che non c'è modo di fare ciò che ho chiesto. Anche [questa domanda] (http://stackoverflow.com/questions/5759667/must-i-include-all-column-attributes-in-an-sql-statement-when-i-want-to-alter-on) avuto questa risposta, 2 anni fa. Supponevo che potessero essere cambiamenti. –

Problemi correlati