2010-08-03 62 views
95

我正在嘗試編寫一個查詢來檢查MySQL中的特定表是否有特定的列,如果沒有 - 創建它。否則什麼都不要做這在任何企業級數據庫中都是一個簡單的過程,但MySQL似乎是個例外。MySQL,檢查列中是否存在SQL列表

我覺得像

IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.COLUMNS 
      WHERE TABLE_NAME='prefix_topic' AND column_name='topic_last_update') 
BEGIN 
ALTER TABLE `prefix_topic` ADD `topic_last_update` DATETIME NOT NULL; 
UPDATE `prefix_topic` SET `topic_last_update` = `topic_date_add`; 
END; 

會的工作,但它失敗得很慘。有沒有辦法?

+0

看到這一點: http://www.cryer.co.uk/brian/mysql/howto_add_column_unless_exists.htm – 2010-08-03 10:58:34

+0

爲什麼不創建它?如果存在,創建將失敗,但你不在乎。 – 2010-08-03 10:59:43

+0

創建發生在一個事務中,並且失敗將會終止整個事務,可悲但是是真的 – clops 2010-08-03 11:02:21

回答

133

@julio

感謝您的SQL示例。我試過查詢,我認爲它需要一個小改動才能正常工作。

SELECT * 
FROM information_schema.COLUMNS 
WHERE 
    TABLE_SCHEMA = 'db_name' 
AND TABLE_NAME = 'table_name' 
AND COLUMN_NAME = 'column_name' 

這對我有效。

謝謝!

+0

它從我的有限研究並非所有的主機環境都有一個information_schema數據庫我已經使用的所有cpanel環境都有它提供的解決方案取決於這個數據庫的存在 – cardi777 2014-03-10 01:26:31

+2

這個答案比使用「SHOW COLUMNS」更好,因爲它使用ANSI標準方法獲得表信息,不像SHOW COLUMNS,它是MySQL特有的,所以這個解決方案將會w與其他數據庫一起使用。使用「information_schema」聽起來很奇怪,你會認爲這不是標準的SQL方法來做到這一點,但它是。 – orrd 2014-03-25 19:46:21

+3

請注意,此答案只會讓您瞭解有關列存在的信息。如果你想有條件地執行一些DDL語句,你必須將整個事件包裝在允許像「IF」等語句的過程中。參見http://stackoverflow.com/questions/7384711/if-conditional- in-sql-script-for-mysql中有關如何在列和條件DML語句的測試周圍包裝過程的示例。 – 2014-07-23 20:14:55

5

從信息架構中只選擇column_name,並將此查詢的結果放入變量中。然後測試變量以決定表是否需要更改。

P.S.不要爲COLUMNS表指定TABLE_SCHEMA。

+1

我對MySQL比較陌生,你可能會在這裏發表一個小例子嗎? – clops 2010-08-03 11:01:23

5

只是爲了幫助別人誰是尋找什麼@Mchi被描述的一個具體的例子,你可以試試

SELECT * FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = 'my_table' AND COLUMN_NAME = 'my_column'

如果返回false(零個結果),那麼你知道列不存在。

178

這對我很好。

SHOW COLUMNS FROM `table` LIKE 'fieldname'; 

使用PHP它會是這樣的......

$result = mysql_query("SHOW COLUMNS FROM `table` LIKE 'fieldname'"); 
$exists = (mysql_num_rows($result))?TRUE:FALSE; 
+5

問題不是如何使用php + sql或java + sql來做到這一點,這是如何使用純SQL/MySQL的,因此downvote – Yura 2012-06-18 09:54:58

+42

你回答這個問題+一些信息,幫助我和其他人,+1 – 2012-11-22 22:38:01

+0

@MFoo謝謝Mfoo,你救了我的一天!像魅力一樣工作。除了爲此任務創建過程之外,最好的解決方案之一。 – webblover 2014-02-14 17:49:50

7

下面是使用純PHP沒有INFORMATION_SCHEMA數據庫做的另一種方式:

$chkcol = mysql_query("SELECT * FROM `my_table_name` LIMIT 1"); 
$mycol = mysql_fetch_array($chkcol); 
if(!isset($mycol['my_new_column'])) 
    mysql_query("ALTER TABLE `my_table_name` ADD `my_new_column` BOOL NOT NULL DEFAULT '0'"); 
+0

爲什麼你想避免使用information_schema?只是爲了這個目的而存在。 (另外,這個線程已經很老了,已經得到了回答。) – Leigh 2012-04-07 04:07:46

+1

在我的測試中,這比使用information_schema大約快10-50倍。它確實要求表格至少有一行,這是你無法保證的。 – Martijn 2013-01-28 10:07:43

+0

如果數組鍵存在,但是值爲** NULL **,則isset()將拋棄'false'。最好使用'array_key_exists()'如'if(!array_key_exists('my_new_column',$ mycol))' – 2016-01-20 08:47:43

5

我把這個存儲程序以及從@ lain上面的註釋開始,如果您需要多次調用它(並且不需要php),那麼該方法很好:

delimiter // 
-- ------------------------------------------------------------ 
-- Use the inforamtion_schema to tell if a field exists. 
-- Optional param dbName, defaults to current database 
-- ------------------------------------------------------------ 
CREATE PROCEDURE fieldExists (
OUT _exists BOOLEAN,  -- return value 
IN tableName CHAR(255), -- name of table to look for 
IN columnName CHAR(255), -- name of column to look for 
IN dbName CHAR(255)  -- optional specific db 
) BEGIN 
-- try to lookup db if none provided 
SET @_dbName := IF(dbName IS NULL, database(), dbName); 

IF CHAR_LENGTH(@_dbName) = 0 
THEN -- no specific or current db to check against 
    SELECT FALSE INTO _exists; 
ELSE -- we have a db to work with 
    SELECT IF(count(*) > 0, TRUE, FALSE) INTO _exists 
    FROM information_schema.COLUMNS c 
    WHERE 
    c.TABLE_SCHEMA = @_dbName 
    AND c.TABLE_NAME = tableName 
    AND c.COLUMN_NAME = columnName; 
END IF; 
END // 
delimiter ; 

fieldExists

mysql> call fieldExists(@_exists, 'jos_vm_product', 'child_option', NULL) // 
Query OK, 0 rows affected (0.01 sec) 

mysql> select @_exists // 
+----------+ 
| @_exists | 
+----------+ 
|  0 | 
+----------+ 
1 row in set (0.00 sec) 

mysql> call fieldExists(@_exists, 'jos_vm_product', 'child_options', 'etrophies') // 
Query OK, 0 rows affected (0.01 sec) 

mysql> select @_exists // 
+----------+ 
| @_exists | 
+----------+ 
|  1 | 
+----------+ 
+0

MIster @quickshiftin,非常感謝。這可以幫助我檢查一個表是否可以過期**,通過_checking_ if有一個'ExpirationDate'字段。 – 2017-02-03 00:12:26

+0

@JeancarloFontalvo我的榮幸!同時檢查我的[mysql-inspectors項目](https://github.com/quickshiftin/mysql-inspectors)我開始用更高級別的方法檢查模式。 – quickshiftin 2017-02-03 00:15:31

+0

OMG它就像一個圖書館。感謝分享它先生! – 2017-02-03 00:37:11

1

工作我使用這個簡單的腳本:

mysql_query("select $column from $table") or mysql_query("alter table $table add $column varchar (20)"); 

它的工作原理,如果你已經連接到數據庫。

+0

這隻有在表中也碰巧有數據行時纔有效。但是如果表格是空的,這是行不通的。 – orrd 2014-03-25 19:08:19

+0

不完美,使用舊的驅動程序,如果表爲空,輸入不能逃脫,但我喜歡你是如何在一行中做到的。 +1 – 2015-01-05 21:06:34

0

不要把ALTER TABLE/MODIFY COLS或任何其他這樣的表模操作放在TRANSACTION中。事務是爲了能夠回滾QUERY故障,而不是用於ALTERATION ...它會在事務中每次出錯。

只需在表上運行SELECT *查詢並檢查列是否存在...

0

非常感謝Mfoo,如果表中不存在動態添加列的真正好腳本。 我用PHP改進了他的答案。 腳本還幫助您查找實際需要多少表「添加列」 mysql命令。只是品嚐配方。像魅力一樣工作。

<?php 
ini_set('max_execution_time', 0); 

$host = 'localhost'; 
$username = 'root'; 
$password = ''; 
$database = 'books'; 

$con = mysqli_connect($host, $username, $password); 
if(!$con) { echo "Cannot connect to the database ";die();} 
mysqli_select_db($con, $database); 
$result=mysqli_query($con, 'show tables'); 
$tableArray = array(); 
while($tables = mysqli_fetch_row($result)) 
{ 
    $tableArray[] = $tables[0];  
} 

$already = 0; 
$new = 0; 
for($rs = 0; $rs < count($tableArray); $rs++) 
{ 
    $exists = FALSE; 

    $result = mysqli_query($con, "SHOW COLUMNS FROM ".$tableArray[$rs]." LIKE 'tags'"); 
    $exists = (mysqli_num_rows($result))?TRUE:FALSE; 

    if($exists == FALSE) 
    { 
     mysqli_query($con, "ALTER TABLE ".$tableArray[$rs]." ADD COLUMN tags VARCHAR(500) CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL"); 
     ++$new; 
     echo '#'.$new.' Table DONE!<br/>'; 
    } 
    else 
    { 
     ++$already; 
     echo '#'.$already.' Field defined alrady!<br/>';  
    } 
    echo '<br/>'; 
} 
?> 
0

這工作讓我有樣PDO:

public function GetTableColumn() {  
$query = $this->db->prepare("SHOW COLUMNS FROM `what_table` LIKE 'what_column'"); 
try{    
    $query->execute();           
    if($query->fetchColumn()) { return 1; }else{ return 0; } 
    }catch(PDOException $e){die($e->getMessage());}  
}