MySQL,使用SQL检查表中是不是存在列
Posted
技术标签:
【中文标题】MySQL,使用SQL检查表中是不是存在列【英文标题】:MySQL, Check if a column exists in a table with SQLMySQL,使用SQL检查表中是否存在列 【发布时间】:2011-03-24 16:09:38 【问题描述】:我正在尝试编写一个查询来检查 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;
会工作,但它失败了。有什么办法吗?
【问题讨论】:
看到这个:cryer.co.uk/brian/mysql/howto_add_column_unless_exists.htm 为什么不直接创建呢?如果存在,创建将失败,但你不在乎。 创建发生在事务内部,失败将终止整个事务,可悲但真实 @haim — 谢谢提醒,但链接中建议的查询仅在过程中有效:( DDL 语句导致当前事务中的隐式提交。 dev.mysql.com/doc/refman/5.0/en/implicit-commit.html 【参考方案1】:这对我很有效。
SHOW COLUMNS FROM `table` LIKE 'fieldname';
使用 php 会是这样的......
$result = mysql_query("SHOW COLUMNS FROM `table` LIKE 'fieldname'");
$exists = (mysql_num_rows($result))?TRUE:FALSE;
【讨论】:
你回答了这个问题 + 一些对我和其他人有帮助的信息,+1 @Mfoo 谢谢 Mfoo,你拯救了我的一天!像魅力一样工作。除了为此任务创建程序之外的最佳解决方案之一。 Yura:纯粹的 SQL / MySQL 答案是他说使用“SHOW COLUMNS FROM table LIKE 'fieldname'”的第一部分。您可以忽略 PHP 代码,这只是您碰巧使用 PHP 时检索和解释结果的一种方式的示例。 找不到存储过程SHOW
@codenamezero 我假设您指的是使用 MSSQL,这个问题是关于 MySQL 的。 MSSQL 参考this post【参考方案2】:
@julio
感谢 SQL 示例。我尝试了查询,我认为它需要进行一些小改动才能使其正常工作。
SELECT *
FROM information_schema.COLUMNS
WHERE
TABLE_SCHEMA = 'db_name'
AND TABLE_NAME = 'table_name'
AND COLUMN_NAME = 'column_name'
这对我有用。
谢谢!
【讨论】:
从我有限的研究看来,并非所有托管环境都有 information_schema 数据库。我用过的所有 cpanel 环境都有它。此提供的解决方案取决于现有的此数据库。 这个答案比使用“SHOW COLUMNS”更好,因为它使用 ANSI 标准方式来获取表信息,这与特定于 MySQL 的 SHOW COLUMNS 不同。所以这个解决方案将适用于其他数据库。使用“information_schema”听起来很奇怪,你会认为这不是标准的 SQL 方法,但它确实是。 请注意,此答案只会为您提供有关列存在的信息。如果你想有条件地执行一些 DDL 语句,你必须将整个事情包装在一个允许像IF
等语句的过程中。有关如何围绕测试包装一个过程的示例,请参见 ***.com/questions/7384711/…列和条件 DML 语句。
@Iain : ***.com/questions/32962149/… 我参考了你的答案
这比下面的“SHOW COLUMNS”方法更好,因为可以在参数化查询中使用,从而降低 SQL 注入的风险。只是想添加您可以使用 DATABASE() 函数来填充 TABLE_SCHEMA 列。【参考方案3】:
只是为了帮助任何正在寻找@Mchl 描述的具体示例的人,请尝试类似
SELECT * FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = 'my_schema' AND TABLE_NAME = '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'
【参考方案4】:
我把这个存储过程和上面@lain 的 cmets 放在一起,如果你需要多次调用它(而不需要 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 |
+----------+
【讨论】:
先生@quickshiftin,非常感谢。这有助于我检查表是否过期,方法是检查是否有ExpirationDate
字段。 ?
@JeancarloFontalvo 我的荣幸!另请查看我的mysql-inspectors project 我开始使用更高级别的方法检查架构。
天啊,这就像一个图书馆?。谢谢楼主分享!【参考方案5】:
以下是使用没有 information_schema 数据库的普通 PHP 的另一种方法:
$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'");
【讨论】:
为什么要避免使用 information_schema?它的存在就是为了这个目的。 (另外,这个帖子很老了,已经回答了。) 在我的测试中,这比使用 information_schema 快大约 10-50 倍。它确实要求表格至少有一行,但您不能总是保证。 如果数组键存在但值为 NULL,isset()
将抛出“false”。最好像if( !array_key_exists( 'my_new_column', $mycol ) )
一样使用array_key_exists()
这个答案让我大吃一惊,因为我忽略了一个简单的isset()
检查。它不能解决问题,但如果您已经需要执行选择查询并将结果保存在内存中,那就更好了。【参考方案6】:
仅从信息模式中选择 column_name 并将此查询的结果放入变量中。然后测试变量以确定表是否需要更改。
附:不要忘记为 COLUMNS 表指定 TABLE_SCHEMA。
【讨论】:
我对 MySQL 比较陌生,你能在这里发布一个小例子吗?【参考方案7】:我正在使用这个简单的脚本:
mysql_query("select $column from $table") or mysql_query("alter table $table add $column varchar (20)");
如果您已经连接到数据库,它就可以工作。
【讨论】:
这只有在表中也有数据行的情况下才有效。但如果表是空的,这将不起作用。 不完美,使用旧驱动程序,如果表为空则不起作用,输入未转义,但我喜欢你在一行中的做法。 +1【参考方案8】:这适用于我的示例 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());
【讨论】:
【参考方案9】:请勿将 ALTER TABLE/MODIFY COLS 或任何其他此类表 mod 操作放入 TRANSACTION 中。事务是为了能够回滚 QUERY 失败而不是 ALTERations...它每次在事务中都会出错。
只需对表运行 SELECT * 查询并检查该列是否存在...
【讨论】:
MySQL 中的ALTER
(以及类似的 DDL)确实(隐式)提交了事务。但是使用 SELECT * 会在网络中产生很大的开销来检查列的存在。您可以改为尝试SELECT my_col_to_check FROM t LIMIT 0
:如果mysql 生成错误,则列可能不存在(仍然检查错误,因为它可能是网络问题或其他原因!);如果它没有产生错误,那么列存在。我不确定这是检查列是否存在的最佳方法。【参考方案10】:
非常感谢 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/>';
?>
【讨论】:
以上是关于MySQL,使用SQL检查表中是不是存在列的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 python pyodbc 检查表中是不是存在列?