2016-02-25 81 views
2

我是MySQL的新手。我用Char數據類型設計了幾個表。現在我想要將所有char數據類型列更改爲具有Char中提及的相應大小的Varchar。更改整個數據庫中列的數據類型 - MySQL

For example. 
Existing - Phone Char(10) 
Expected - Phone Varchar(10) 

大約有50張桌子。我知道如何改變每個表格和列的數據類型,但有沒有更好的方法來改變單次數據類型。

+0

嘗試此查詢'ALTER TABLE db.table 修改列的電話VARCHAR(100);' –

+0

簡短的回答是,你不能改變的數據類型一些列基於列數據類型,在所有表中沒有指定表名和列名。 我甚至不打算寫一個腳本來解決這個問題。 – dirbacke

回答

2

如果您不能編寫腳本來完成這項工作,請編寫腳本來編寫腳本來完成這項工作!

你想了一堆ALTER TABLE語句:

SET SESSION group_concat_max_len = 1000000; -- Bumps the limit of 1028 
SELECT GROUP_CONCAT(
    CONCAT(
     'ALTER TABLE `', 
     table_name, 
     '` MODIFY COLUMN `', 
     column_name, 
     '` VARCHAR(', 
     character_maximum_length, 
     ')' 
    ) 
SEPARATOR ';\n') your_alter_statements 
FROM information_schema.columns 
WHERE table_schema = 'concrete' 
AND data_type = 'char'; 

這會導致:

ALTER TABLE `table1` MODIFY COLUMN `col1` VARCHAR(10); 
ALTER TABLE `table1` MODIFY COLUMN `col2` VARCHAR(10); 
ALTER TABLE `table2` MODIFY COLUMN `col1` VARCHAR(10); 
ALTER TABLE `table3` MODIFY COLUMN `col1` VARCHAR(10); 
ALTER TABLE `table3` MODIFY COLUMN `col2` VARCHAR(10); 

運行這一點,你可以早點回家!

更新:通過添加group_concat_max_len停止截斷。根據列長度制定長度動態。

+0

我自己準備了一個與您的解決方案有點相似的SQL。無論如何感謝您的幫助。 – StackUser

+0

我已經給你一個例子作爲字符(10),但每個表的大小不同。 – StackUser

+0

啊,所以你想保持大小。所以如果它是CHAR(99),那麼使它成爲VARCHAR(99)? –

0

分析完網頁後,我得到了答案,並使用此查詢更改了數據類型。

select 
concat('ALTER TABLE ', table_name,' MODIFY COLUMN ', column_name,' ', REPLACE (column_type, 'char', 'varchar'),';') 
from information_schema.columns 
where 
data_type='char' 
and table_schema='DBName'; 
+0

我的腳本比較好。每條語句最後都會換行,表和列名都會被轉義,當您複製結果時,每條語句都不會包含在單引號中(從Workbench進行復制就是這樣做),而且您的REPLACE是冗餘的。 –

+0

@AdrianLynch,SQL不需要爲每個語句添加新行,但分號就足夠了 – AamirR

1

MySQL只一個班輪解決方案:

SELECT 'ALTER TABLE ',TABLE_NAME, ' MODIFY COLUMN ',COLUMN_NAME, CONCAT(' VARCHAR(', CHARACTER_MAXIMUM_LENGTH, ');') 
    FROM INFORMATION_SCHEMA.COLUMNS where DATA_TYPE = 'char' AND TABLE_SCHEMA='concrete' 

上面的查詢將返回所有ALTER TABLE聲明,如下圖所示例子:

ALTER TABLE  tablename1 MODIFY COLUMN col_name1 VARCHAR(17); 
ALTER TABLE  tablename2 MODIFY COLUMN col_name2 VARCHAR(17); 
ALTER TABLE  tablename3 MODIFY COLUMN col_name3 VARCHAR(60); 

複製生成的行和執行,所以你可以去家庭更早。

此外,以下是PHP/MySQL的解決方案:

// Initialise Connection 
define('DB_HOST', 'HOST_NAME_HERE'); 
define('DB_NAME', 'DB_NAME_HERE'); 
define('DB_USER_NAME', 'DB_USER_NAME_HERE'); 
define('DB_PASSWORD', 'DB_PASSWORD_HERE'); 

$pdo = new PDO('mysql:host=' . DB_HOST . ';dbname=' . DB_NAME, DB_USER_NAME, DB_PASSWORD, [ 
    PDO::ATTR_PERSISTENT => false, 
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, 
    PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8" 
]); 

// Get a list of CHAR columns 
$sql = "SELECT TABLE_NAME, COLUMN_NAME, CHARACTER_MAXIMUM_LENGTH, IS_NULLABLE, COLUMN_DEFAULT 
     FROM INFORMATION_SCHEMA.COLUMNS where DATA_TYPE = 'char' AND TABLE_SCHEMA='" . DB_NAME . "'"; 

$stmt = $pdo->prepare($sql); 
$stmt->execute(); 
$data = $stmt->fetchAll(PDO::FETCH_ASSOC); 

// Change CHAR to VARCHAR 
foreach ($data as $rec) { 
    $ddq = 'ALTER TABLE ' . $rec['TABLE_NAME'] . ' CHANGE ' . $rec['COLUMN_NAME'] . ' ' . $rec['COLUMN_NAME'] . ' VARCHAR(' . 
      $rec['CHARACTER_MAXIMUM_LENGTH'] . ') ' . ($rec['IS_NULLABLE'] == 'YES' ? 'NULL' : 'NOT NULL') . (isset($rec['COLUMN_DEFAULT']) ? " DEFAULT '{$rec['COLUMN_DEFAULT']}'" : ''); 
    $pdo->query($ddq); 
} 
+0

它純粹來自MySQL數據庫結尾 – StackUser

+0

@NewUser,只有如果你有一個PHP環境的MySQL,你可以在腳本 – AamirR

+0

之上運行@NewUser,udpated我的答案,只添加mysql – AamirR