如何在MySQL数据库中获取枚举值?

时间:2010-02-28 04:09:45

标签: php mysql

我想自动使用DB中的枚举值填充我的下拉列表。这在MySQL中是否可行?

25 个答案:

答案 0 :(得分:91)

我有一个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;
}

答案 1 :(得分:48)

您可以通过查询来获取值:

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

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

  • 如果你很懒,直接进入数组(尽管MySQL的单引号转义可能不兼容),或者
  • $ options_array = str_getcsv($ options,',',“'”)可能会起作用(如果你改变子字符串以跳过开括号和右括号),或者
  • 正则表达式

答案 2 :(得分:29)

MySQL Reference

  

如果你想确定所有可能的   ENUM列的值,使用SHOW   COLUMNS FROM tbl_name LIKE enum_col   并在中解析ENUM定义   输入输出列。

你会想要这样的东西:

$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;
}

答案 3 :(得分:11)

这就像上面的很多,但是给你的结果没有循环,并且你想要你真正想要的东西:一个用于生成选择选项的简单数组。

BONUS:适用于SET和ENUM字段类型。

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

$ option_array: 排列 (     [0] =>红色     [1] =>绿色     [2] =>蓝色 )

答案 4 :(得分:9)

您可以将字符串解析为CSV(逗号分隔值)字符串。 PHP有一个很棒的内置函数,名为str_getcsv,它将CSV字符串转换为数组。

// 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
)

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

$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

答案 5 :(得分:9)

这是Chris Komlenic的8 Reasons Why MySQL's ENUM Data Type Is Evil之一:

  

4.获取不同ENUM成员的列表很痛苦。

     
    

一个非常常见的需求是使用数据库中的可能值填充选择框或下拉列表。像这样:

         

选择颜色:

         

[ select box ]

         

如果这些值存储在名为“colors”的引用表中,您只需要:SELECT * FROM colors ...然后可以解析它以动态生成下拉列表。您可以在参考表中添加或更改颜色,您的性感订单将自动更新。真棒。

         

现在考虑一下邪恶的ENUM:你如何提取会员名单?您可以在表中查询ENUM列中的DISTINCT值,但这只会返回实际使用并显示在表中的值,而不一定是所有可能的值。您可以使用脚本语言查询INFORMATION_SCHEMA并从查询结果中解析它们,但这不必要地复杂化。实际上,我不知道提取ENUM列的成员列表的任何优雅,纯粹的SQL方式。

  

答案 6 :(得分:6)

更新的方式,这对我有用:

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;
}

最终,与“enum()”分开时的枚举值只是一个CSV字符串,所以要解析它!

答案 7 :(得分:5)

这里是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);

答案 8 :(得分:2)

这个帖子中每个其他答案的问题是它们都没有正确解析枚举中字符串的所有特殊情况。

抛出循环的最大特殊情况字符是单引号,因为它们被编码为2个单引号!因此,例如,值为'a'的枚举被编码为enum('''a''')。太可怕了吧?

嗯,解决方案是使用MySQL为你解析数据!

由于其他人都在这个线程中使用PHP,这就是我将要使用的。以下是完整的代码。我会在之后解释。参数$FullEnumString将保存整个枚举字符串,从您要从所有其他答案中使用的任何方法中提取。 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语法转义的字符串列表。接下来,我们希望能够从中获取真实数据。所以你只需运行"SELECT ".$Matches[1],就可以在第一条记录中找到完整的字符串列表!

所以只需用FetchRow(RunQuery(...))取出该记录就可以了。

如果您想在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;

P.S。为了阻止任何人说些什么,不,我不相信这种方法可以导致SQL注入。

答案 9 :(得分:2)

对于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
)

答案 10 :(得分:2)

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

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

你得到了价值,例如:enum(&#39;男&#39;,&#39;女&#39;)

这是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;
}
?>

答案 11 :(得分:2)

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"
}

答案 12 :(得分:2)

以下是Patrick Savalle为Laravel框架提供的相同功能

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;

}

答案 13 :(得分:2)

试试这个

describe table columnname

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

答案 14 :(得分:2)

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


}

答案 15 :(得分:2)

我只想在查询时添加 jasonbar 所说的内容:

SHOW columns FROM table

如果以数组形式得到结果,它将如下所示:

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

其中[n]和[text]给出相同的值 在我找到的任何文档中都没有说明。很高兴知道还有什么。

答案 16 :(得分:1)

你们中没人会想到,如果您使用枚举字段,那就意味着要分配的值被称为“先验”。

因此,如果知道这些值是“先验”,最好的方法就是通过一个非常简单的Enum类。

接吻规则并保存一个数据库调用。

<?php
class Genre extends \SplEnum {
 const male = "Male";
 const female = "Female";
}

http://it2.php.net/manual/en/class.splenum.php

答案 17 :(得分:1)

要获取可能值列表已经有详细记录,但expanding on another answer that returned the values in parenthesis,我想将它们删除,留下逗号分隔列表,这样我就可以在需要时使用爆炸类型函数得到一个数组。

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个字符,删除尾部括号。

答案 18 :(得分:1)

所有人都使用一些奇怪而复杂的正则表达式x)

这是我没有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()'"));
}

答案 19 :(得分:1)

这对我有用:

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)

答案 20 :(得分:0)

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

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

运行这个sql我得到:enum(&#39; BDBL&#39;,&#39; AB Bank&#39;)

然后我使用以下代码过滤了值:

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

Out put:

array(2){   [0] =&GT;   字符串(4)&#34; BDBL&#34;   [1] =&GT;   字符串(7)&#34; AB Bank&#34; }

答案 21 :(得分:0)

PHP 5.6+

$mysqli = new mysqli("example.com","username","password","database");
$result = $mysqli->query("SELECT COLUMN_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='table_name' AND COLUMN_NAME='column_name'");
$row = $result->fetch_assoc();
var_dump($row);

答案 22 :(得分:0)

DELIMITER //

    DROP FUNCTION IF EXISTS ENUM_VALUES;

    CREATE FUNCTION ENUM_VALUES(

        _table_name VARCHAR(64), 
        _col_name VARCHAR(64)

    ) RETURNS JSON

        BEGIN

            RETURN (
                SELECT CAST(CONCAT('[', REPLACE(SUBSTRING(COLUMN_TYPE, 6, LENGTH(COLUMN_TYPE) - 6), "'", '"'), ']') AS JSON)
                  FROM information_schema.COLUMNS
                 WHERE TABLE_SCHEMA = 'db_name'
                   AND TABLE_NAME   = _table_name
                   AND COLUMN_NAME  = _col_name
                   AND DATA_TYPE    = 'enum'
            );

        END //

DELIMITER ;

示例:

SELECT ENUM_VALUES('table_name', 'col_name');

答案 23 :(得分:0)

选择     SUBSTRING(COLUMN_TYPE,6,LENGTH(COLUMN_TYPE)-6)AS VAL 从     information_schema.COLUMNS 哪里     TABLE_NAME ='文章' 和     COLUMN_NAME ='状态'

不适用于枚举('','X''XX')

答案 24 :(得分:0)

这是自定义WordPress表的解决方案。这将适用于其中没有逗号(,)的ENUM值

function get_enum_values($wpdb, $table, $field) {

    $values = array();
    $table = "{$wpdb->prefix}{$table}";
    $query = "SHOW COLUMNS FROM {$table} WHERE Field = '{$field}'";
    $results = $wpdb->get_results($query, ARRAY_A);

    if (is_array($results) && count($results) > 0) {

        preg_match("/^enum\(\'(.*)\'\)$/", $results[0]['Type'], $matches);

        if (is_array($matches) && isset($matches[1])) {

            $values = explode("','", $matches[1]);

        }

    }

    return $values;

}