我怎样才能在MySQL数据库中枚举可能的值?

我想填充我的下拉列表中自动从数据库枚举可能的值。 这在MySQL中可能吗?

我有一个codeigniter版本给你。 它也从这些值中除去引号。

function get_enum_values( $table, $field ) { $type = $this->db->query( "SHOW COLUMNS FROM {$table} WHERE Field = '{$field}'" )->row( 0 )->Type; preg_match("/^enum\(\'(.*)\'\)$/", $type, $matches); $enum = explode("','", $matches[1]); return $enum; } 

你可以通过查询来得到这些值:

 SELECT SUBSTRING(COLUMN_TYPE,5) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA='databasename' AND TABLE_NAME='tablename' AND COLUMN_NAME='columnname' 

从那里你需要把它转换成一个数组:

  • 如果你懒惰的话,直接把数组直接放到数组中(尽pipeMySQL的单引号转义可能是不兼容的),或者
  • $ options_array = str_getcsv($ options,',',“'”)可能会起作用(如果你改变子串来跳过开始和结束括号),或者
  • 一个正则expression式

MySQL参考

如果要确定ENUM列的所有可能值,请使用SHOW COLUMNS FROM tbl_name LIKE enum_col并在输出的Type列中parsingENUM定义。

你会想要的东西,如:

 $sql = "SHOW COLUMNS FROM `table` LIKE 'column'"; $result = $db->query($sql); $row = $result->fetchRow(); $type = $row['Type']; preg_match('/enum\((.*)\)$/', $type, $matches); $vals = explode(',', $matches[1]); 

这会给你报价值。 MySQL始终使用单引号括起来。 值中的单引号会被单引号转义。 您可以安全地调用每个数组元素的trim($val, "'") 。 你会想把''换成'

以下将返回不带引号的$ trimmedvals数组项目:

 $trimmedvals = array(); foreach($vals as $key => $value) { $value=trim($value, "'"); $trimmedvals[] = $value; } 

这就像上面的很多,但给你的结果没有循环,并让你想你真的想要:一个简单的数组产生select选项。

奖金:它适用于SET以及ENUM字段types。

 $result = $db->query("SHOW COLUMNS FROM table LIKE 'column'"); if ($result) { $option_array = explode("','",preg_replace("/(enum|set)\('(.+?)'\)/","\\2", $result[0]->Type)); } 

$ option_array:Array([0] => red [1] => green [2] => blue)

您可以像parsingCSV(逗号分隔值)string一样parsingstring。 PHP有一个很好的内置函数str_getcsv,它将CSVstring转换为数组。

 // This is an example to test with $enum_or_set = "'blond','brunette','redhead'"; // Here is the parser $options = str_getcsv($enum_or_set, ',', "'"); // Output the value print_r($options); 

这应该给你类似于以下内容:

 Array ( [0] => blond [1] => brunette [2] => redhead ) 

此方法还允许您在string中使用单引号(注意使用两个单引号):

 $enum_or_set = "'blond','brunette','red''head'"; Array ( [0] => blond [1] => brunette [2] => red'head ) 

有关str_getcsv函数的更多信息,请查看PHP手册: http ://uk.php.net/manual/en/function.str-getcsv.php

这是Chris Komlenic的8个理由之一为什么MySQL的ENUM数据types是邪恶的 :

4.列出不同的ENUM成员是一个痛苦。

一个非常常见的需求是用数据库中的可能值填充select框或下拉列表。 喜欢这个:

select颜色:

[ select box ]

如果这些值存储在一个名为'colors'的参考表中,那么所有你需要的是: SELECT * FROM colors …然后可以parsing出来dynamic生成下拉列表。 您可以添加或更改参考表中的颜色,您的性感订单将自动更新。 真棒。

现在考虑一下这个邪恶的ENUM:你如何提取成员列表? 您可以在表中查询ENUM列中的DISTINCT值,但这只会返回中实际使用的值,而不一定是所有可能的值。 您可以使用脚本语言查询INFORMATION_SCHEMA并将其从查询结果中parsing出来,但这不必要的复杂。 事实上,我不知道任何优雅的,纯粹的SQL方法来提取ENUM列的成员列表。

一个更新的方式做到这一点,这为我工作:

 function enum_to_array($table, $field) { $query = "SHOW FIELDS FROM `{$table}` LIKE '{$field}'"; $result = $db->query($sql); $row = $result->fetchRow(); preg_match('#^enum\((.*?)\)$#ism', $row['Type'], $matches); $enum = str_getcsv($matches[1], ",", "'"); return $enum; } 

最后,从“枚举()”分隔的枚举值只是一个CSVstring,所以parsing它!

听到的是mysqli

 function get_enum_values($mysqli, $table, $field ) { $type = $mysqli->query("SHOW COLUMNS FROM {$table} WHERE Field = '{$field}'")->fetch_array(MYSQLI_ASSOC)['Type']; preg_match("/^enum\(\'(.*)\'\)$/", $type, $matches); $enum = explode("','", $matches[1]); return $enum; } $deltypevals = get_enum_values($mysqli, 'orders', 'deltype'); var_dump ($deltypevals); 

我只是想添加到什么jasonbar说,当像这样查询:

 SHOW columns FROM table 

如果以数组的forms得到结果,它将如下所示:

 array([0],[Field],[1],[Type],[2],[Null],[3],[Key],[4],[Default],[5],[Extra]) 

其中[n]和[文本]给出相同的值。
在我find的任何文档中都没有真正告知。 只要知道还有什么。

 $row = db_fetch_object($result); if($row){ $type = $row->Type; preg_match_all("/'([^']+)'/", $type, $matches,PREG_PATTERN_ORDER ); return $matches[1]; } 

尝试这个

 describe table columnname 

为您提供该表中关于该列的所有信息;

帕特里克·萨维尔(Patrick Savalle)为拉拉维尔(Laravel)框架提供的function也是如此

 function get_enum_values($table, $field) { $test=DB::select(DB::raw("show columns from {$table} where field = '{$field}'")); preg_match('/^enum\((.*)\)$/', $test[0]->Type, $matches); foreach( explode(',', $matches[1]) as $value ) { $enum[] = trim( $value, "'" ); } return $enum; } 

Codeigniter适配版本作为某些模型的方法:

 public function enum_values($table_name, $field_name) { $query = $this->db->query("SHOW COLUMNS FROM `{$table_name}` LIKE '{$field_name}'"); if(!$query->num_rows()) return array(); preg_match_all('~\'([^\']*)\'~', $query->row('Type'), $matches); return $matches[1]; } 

结果:

 array(2) { [0]=> string(13) "administrator" [1]=> string(8) "customer" } 

您可以使用此语法在MySQL QUERY中获取枚举可能的值:

 $syntax = "SELECT COLUMN_TYPY FROM information_schema.`COLUMNS` WHERE TABLE_NAME = '{$THE_TABLE_NAME}' AND COLUMN_NAME = '{$THE_COLUMN_OF_TABLE}'"; 

你会得到价值,例如:enum('男','女')

这是例子sytax php:

 <?php function ($table,$colm){ // mysql query. $syntax = mysql_query("SELECT COLUMN_TYPY FROM information_schema.`COLUMNS` WHERE TABLE_NAME = '$table' AND COLUMN_NAME ='$colm'"); if (!mysql_error()){ //Get a array possible values from table and colm. $array_string = mysql_fetch_array($syntax); //Remove part string $string = str_replace("'", "", $array_string['COLUMN_TYPE']); $string = str_replace(')', "", $string); $string = explode(",",substr(5,$string)); }else{ $string = "error mysql :".mysql_error(); } // Values is (Examples) Male,Female,Other return $string; } ?> 

你们都使用一些奇怪而复杂的正则expression式x)

这是我的解决scheme没有preg_match:

 function getEnumTypes($table, $field) { $query = $this->db->prepare("SHOW COLUMNS FROM $table WHERE Field = ?"); try {$query->execute(array($field));} catch (Exception $e) {error_log($e->getMessage());} $types = $query->fetchAll(PDO::FETCH_COLUMN|PDO::FETCH_UNIQUE, 1)[$field]; return explode("','", trim($types, "enum()'")); } 

这将为我工作:

 SELECT REPLACE(SUBSTRING(COLUMN_TYPE,6,(LENGTH(COLUMN_TYPE)-6)),"'","") FROM information_schema.COLUMNS WHERE TABLE_SCHEMA='__TABLE_SCHEMA__' AND TABLE_NAME='__TABLE_NAME__' AND COLUMN_NAME='__COLUMN_NAME__' 

接着

 explode(',', $data) 

对于Laravel这个工作:

 $result = DB::select("SHOW COLUMNS FROM `table_name` LIKE 'status';"); $regex = "/'(.*?)'/"; preg_match_all( $regex , $result[0]->Type, $enum_array ); $enum_fields = $enum_array[1]; echo "<pre>"; print_r($enum_fields); 

输出:

 Array ( [0] => Requested [1] => Call Back [2] => Busy [3] => Not Reachable [4] => Not Responding ) 

我以这种方式得到枚举值:

 SELECT COLUMN_TYPE FROM information_schema.`COLUMNS` WHERE TABLE_NAME = 'tableName' AND COLUMN_NAME = 'columnName'; 

运行这个SQL我得到:enum('BDBL','AB银行')

那么我已经使用以下代码过滤了值:

 preg_match("/^enum\(\'(.*)\'\)$/", $type, $matches); $enum = explode("','", $matches[1]); var_dump($enum) ; 

输出:

array(2){[0] => string(4)“BDBL”[1] => string(7)“AB Bank”}

在这个线程中的每个其他答案的问题是,他们都没有妥善parsing在枚举中的string的所有特殊情况。

引起我一个循环的最大的特殊字符是单引号,因为它们自己编码为2个单引号! 因此,例如,一个值为'a' enum('''a''')被编码为enum('''a''') 。 太可怕了吧?

那么,解决scheme就是使用MySQL为你parsing数据!

由于其他人在这个线程中使用PHP,这就是我将使用的。 以下是完整的代码。 我会在后面解释。 参数$FullEnumString将保存整个枚举string,从任何你想使用的方法中提取所有其他答案。 RunQuery()FetchRow() (非关联)支持你最喜欢的数据库访问方法。

 function GetDataFromEnum($FullEnumString) { if(!preg_match('/^enum\((.*)\)$/iD', $FullEnumString, $Matches)) return null; return FetchRow(RunQuery('SELECT '.$Matches[1])); } 

preg_match('/^enum\((.*)\)$/iD', $FullEnumString, $Matches)确认枚举值与我们所期望的相符,即"enum(".$STUFF.")" (之前或之后都没有)。 如果preg_match失败,则返回NULL

这个preg_match还存储在$Matches[1]以奇怪的SQL语法转义的string列表。 接下来,我们希望能够从中获得真实的数据。 所以你只要运行"SELECT ".$Matches[1] ,你就可以在第一个logging中得到完整的string列表!

所以只需用FetchRow(RunQuery(...))来取出这个logging,就完成了。

如果你想在SQL中完成这件事,你可以使用下面的代码

 SET @TableName='your_table_name', @ColName='your_col_name'; SET @Q=(SELECT CONCAT('SELECT ', (SELECT SUBSTR(COLUMN_TYPE, 6, LENGTH(COLUMN_TYPE)-6) FROM information_schema.COLUMNS WHERE TABLE_NAME=@TableName AND COLUMN_NAME=@ColName))); PREPARE stmt FROM @Q; EXECUTE stmt; 

PS为了防止任何人说些什么,不,我不相信这种方法会导致SQL注入。

获取可能值的列表已经有很好的文档logging,但扩展到另一个返回括号中的值的答案 ,我想剥离他们离开我一个逗号分隔的列表,然后允许我使用爆炸types函数,只要我需要获得一个数组。

 SELECT SUBSTRING(COLUMN_TYPE, 6, LENGTH(COLUMN_TYPE) - 6) AS val FROM information_schema.COLUMNS WHERE TABLE_NAME = 'articles' AND COLUMN_NAME = 'status' 

SUBSTRING现在从第6个字符开始,使用比总数短6个字符的长度,删除尾部括号。