Answers:
我有一个适合您的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'
从那里,您需要将其转换为数组:
如果要确定ENUM列的所有可能值,请使用SHOW COLUMNS FROM tbl_name LIKE enum_col并在输出的Type列中解析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, "'")
每个数组元素。您将需要转换''
为just '
。
以下代码将返回$ trimmedvals数组项目,但不带引号:
$trimmedvals = array();
foreach($vals as $key => $value) {
$value=trim($value, "'");
$trimmedvals[] = $value;
}
这就像上面的很多内容一样,但是为您提供了没有循环的结果,并且让您真正想要的是:用于生成选择选项的简单数组。
奖励:它适用于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] =>蓝色)
这是Chris Komlenic解释MySQL的ENUM数据类型为何邪恶的8个原因之一:
4.获取不同的ENUM成员列表是一件很痛苦的事情。
一个非常普遍的需求是使用数据库中的可能值填充选择框或下拉列表。像这样:
选择颜色:
[ select box ]
如果这些值存储在名为“ colors”的参考表中,则您需要做的是:
SELECT * FROM colors
...然后可以将其解析以动态生成下拉列表。您可以在参考表中添加或更改颜色,然后您的性感订单表格将自动更新。太棒了现在考虑邪恶的ENUM:如何提取成员列表?您可以查询表中的ENUM列以获取DISTINCT值,但是这只会返回表中实际使用和存在的值,不一定返回所有可能的值。您可以查询INFORMATION_SCHEMA并使用脚本语言将其从查询结果中解析出来,但这不必要地很复杂。实际上,我不知道提取ENUM列的成员列表的任何优雅的纯SQL方法。
您可以将字符串解析为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/zh/function.str-getcsv.php
str_getcsv
仅适用于PHP 5> = 5.3.0,如果您希望在早期版本中获得此功能,则可以包含此文件。
一种更新的方式,对我有用:
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字符串,因此应将其解析!
这是给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);
这是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;
}
查询时,我只想添加jasonbar所说的内容:
SHOW columns FROM table
如果将结果作为数组输出,则将如下所示:
array([0],[Field],[1],[Type],[2],[Null],[3],[Key],[4],[Default],[5],[Extra])
其中[n]和[text]给出相同的值。
我发现的任何文档中都没有真正告诉您。很高兴知道那里还有什么。
试试这个
describe table columnname
提供有关该表中该列的所有信息;
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"
}
你们所有人都使用一些奇怪而复杂的正则表达式模式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()'"));
}
您可以使用以下语法在MySQL QUERY中获取枚举可能的值:
$syntax = "SELECT COLUMN_TYPY FROM information_schema.`COLUMNS`
WHERE TABLE_NAME = '{$THE_TABLE_NAME}'
AND COLUMN_NAME = '{$THE_COLUMN_OF_TABLE}'";
并且您获得了价值,例如:enum('Male','Female')
这是示例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;
}
?>
对于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
)
该线程中其他所有答案的问题在于,它们中的任何一个都无法正确解析枚举中字符串的所有特殊情况。
使我陷入困境的最大的特殊情况字符是单引号,因为它们本身被编码为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
还将以奇怪的SQL语法转义的字符串列表存储在中$Matches[1]
。因此,接下来,我们希望能够从中获取真实数据。所以你就跑"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;
PS要阻止任何人说些什么,不,我不认为此方法会导致SQL注入。
要获取可能的值列表,已经有充分的文档记录,但是可以扩展到另一个返回括号中值的答案,我想将其删除,然后用逗号分隔的列表给我,然后让我每当我使用爆炸类型函数时就可以使用需要一个数组。
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个字符,删除尾部括号。
对于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);
谁都没有想到过,如果您使用的是枚举字段,那就太了不起了,这意味着要分配的值被称为“先验”。
因此,如果知道这些值是“先验”,最好的方法就是通过一个非常简单的Enum类。
接吻规则并保存一个数据库调用。
<?php
class Genre extends \SplEnum {
const male = "Male";
const female = "Female";
}
我以这种方式获得枚举值:
SELECT COLUMN_TYPE
FROM information_schema.`COLUMNS`
WHERE TABLE_NAME = 'tableName'
AND COLUMN_NAME = 'columnName';
运行此sql,我得到:enum('BDBL','AB Bank')
然后我使用以下代码过滤了值:
preg_match("/^enum\(\'(.*)\'\)$/", $type, $matches);
$enum = explode("','", $matches[1]);
var_dump($enum) ;
输出:
array(2){[0] =>字符串(4)“ BDBL” [1] =>字符串(7)“ AB Bank”}
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');
从information_schema.COLUMNS SELECT SUBSTRING(COLUMN_TYPE,6,LENGTH(COLUMN_TYPE)-6)值TABLE_NAME ='articles AND COLUMN_NAME ='status'的值
不适用于枚举('','X''XX')