2014-04-07 172 views
10

如果我做的:更改列數據類型(默認,NOTNULL ...)

ALTER TABLE testtable MODIFY mycolumn NEWDATATYPE; 

我失去喜歡NOT NULL,評論,默認值等定義?有沒有如何做到這一點?

In PostgreSQL I used

ALTER TABLE testtable ALTER COLUMN mycolumn NEWDATATYPE; 

以及它的作用應該是:更改列數據類型,不接觸任何其他的定義,只給錯誤,如果數據類型是不兼容等(但您可以指定使用)。

我會嘗試一種解決方法,但我做了一個查詢來識別不同表中的幾個列來更新數據類型,現在我已經識別出這個數據已經丟失了,所以我將不得不重新考慮這些信息太。

+0

我得到了[修改要求(http://dev.mysql.com/doc/refman /5.1/en/alter-table.html)所有_column_definition_,我認爲它可能有另一種語法來改變你想要的。 –

回答

4

正如manual page中所述,ALTER TABLE要求定義所有新的類型屬性。

但是,有一種方法可以解決這個問題。您可以使用INFORMATION_SCHEMA meta-data重新構建所需的ALTER查詢。例如,如果我們有簡單的表:

 
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) 

那麼我們可以複製我們的ALTER語句:

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' 

的結果將是:

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

在這裏,我已經離開了@new_type以表明我們可以使用變量(甚至可以直接替換我們的新類型來查詢)。變量爲:

  • 設置我們的變量。

    mysql> SET @new_type := 'VARCHAR(10)', @column_name := 'value'; 
    Query OK, 0 rows affected (0.00 sec) 
    
  • 準備變量prepared statement(這是很長的查詢,但我已經離開上述說明):

    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); 
    
  • 準備聲明:

    mysql> prepare stmt from @sql; 
    Query OK, 0 rows affected (0.00 sec) 
    Statement prepared 
    
  • 最後,執行它:

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

然後,我們會得到我們的數據類型更改爲VARCHAR(10)拯救所有的休息符:

 
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

偉大的提示。記住這一點並不容易,但是當您有近100列的更新時就會簡化。作爲一個加號,如果你可以在你的子句中添加COMMENT和DEFAULT,那將是非常好的,因爲所有的東西都應該被修飾,如:IF(COLUMN_DEFAULT不是NULL,CONCAT('DEFAULT',QUOTE(c.COLUMN_DEFAULT),'' ),''),IF(COLUMN_COMMENT IS NOT NULL AND COLUMN_COMMENT!='',CONCAT('COMMENT',QUOTE(c.COLUMN_COMMENT),''),''),'。這將完成答案。 –

+0

是的,它應該添加爲常見的情況 - 所以我的觀點是顯示整個想法 –

0
ALTER TABLE tableName 
MODIFY COLUMN columnName datatype 
+0

這給了我這個問題的問題。 –

0

當您使用CHANGEMODIFYALTER table_namecolumn_definition必須包括數據類型和所有屬性應適用於新列,除了指數屬性,例如PRIMARY KEYUNIQUE。存在於原定義中但未爲新定義指定的屬性未結轉

假設一列col1被定義爲INT UNSIGNED DEFAULT 1COMMENT 'my column'和修改列如下:

ALTER TABLE t1 MODIFY col1 BIGINT; 

結果列將被定義爲BIGINT,但不包括屬性UNSIGNED DEFAULT 1COMMENT 'my column'。爲了留住他們,語句應該是:

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

當您更改使用CHANGEMODIFYMySQL嘗試對現有列值轉換爲新類型以及可能的數據類型。

請參閱documentation

+0

我看到了文檔,我期望有一種方法可以只改變你想要的。醜陋的方式來改變一個精確的信息。我知道,我無法做到我所要求的。此外[這個問題](http://stackoverflow.com/questions/5759667/must-i-include-all-column-attributes-in-an-sql-statement-when-i-want-to-alter-on) 2年前有過這種迴應。我想這可能是變化。 –