MySQL,检查SQL中是否存在列

clo*_*ops 119 mysql

我正在尝试编写一个查询,以检查MySQL中的特定表是否具有特定列,如果不是 - 创建它.否则什么都不做.这在任何企业级数据库中都是一个简单的过程,但MySQL似乎是个例外.

我觉得有点像

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;
Run Code Online (Sandbox Code Playgroud)

会工作,但它失败了.有办法吗?

Mfo*_*foo 236

这对我很有用.

SHOW COLUMNS FROM `table` LIKE 'fieldname';
Run Code Online (Sandbox Code Playgroud)

使用PHP,它会像...

$result = mysql_query("SHOW COLUMNS FROM `table` LIKE 'fieldname'");
$exists = (mysql_num_rows($result))?TRUE:FALSE;
Run Code Online (Sandbox Code Playgroud)

  • 你回答问题+一些帮助我和其他人的信息,+1 (55认同)
  • Yura:纯SQL/MySQL答案是第一部分,他说使用"SHOW COLUMNS FROM table LIKE'fieldname'".您可以忽略PHP代码,这只是在您碰巧使用PHP时检索和解释结果的一种方法的示例. (8认同)
  • 问题不是如何使用php + sql或java + sql这样做,它是如何使用纯sql/mysql做到这一点因此downvote (6认同)

小智 149

@julio

感谢SQL示例.我尝试了查询,我认为需要进行一些小改动才能使其正常工作.

SELECT * 
FROM information_schema.COLUMNS 
WHERE 
    TABLE_SCHEMA = 'db_name' 
AND TABLE_NAME = 'table_name' 
AND COLUMN_NAME = 'column_name'
Run Code Online (Sandbox Code Playgroud)

这对我有用.

谢谢!

  • 请注意,此答案仅为您提供有关列存在的信息.如果你想有条件地执行一些DDL语句,你必须将整个事情包装在允许诸如`IF`等语句的过程中.参见http://stackoverflow.com/questions/7384711/if-conditional- in-sql-script-for-mysql,以获取如何围绕列和条件DML语句的测试包装过程的示例. (5认同)
  • 这个答案比使用"SHOW COLUMNS"更好,因为它使用ANSI标准方式获取表信息,这与MySQL特有的SHOW COLUMNS不同.因此,此解决方案将适用于其他数据库.使用"information_schema"听起来很奇怪,你会认为这不是标准的SQL方法,但它确实如此. (2认同)

jul*_*lio 13

只是为了帮助那些正在寻找@Mchl描述的具体例子的人,试试类似的东西

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

如果它返回false(零结果),那么您知道该列不存在.

  • 我相信它应该是`TABLE_NAME = 'my_table'`,TABLE_SCHEMA是表所在的模式。即`SELECT * FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = 'my_schema' AND TABLE_NAME = 'my_table' AND COLUMN_NAME = 'my_column'` (2认同)

wva*_*los 9

以下是使用普通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'");
Run Code Online (Sandbox Code Playgroud)

  • 在我的测试中,这比使用 information_schema 快大约 10-50 倍。它确实要求表至少有一行,但您不能总是保证这一点。 (2认同)

qui*_*tin 9

我把这个存储过程与上面@ 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 ;
Run Code Online (Sandbox Code Playgroud)

与...合作 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 |
+----------+
Run Code Online (Sandbox Code Playgroud)


Mch*_*chl 7

从信息模式中仅选择column_name,并将此查询的结果放入变量中.然后测试变量以确定表是否需要更改.

PS也不要为COLUMNS表指定TABLE_SCHEMA.