2010-02-28 88 views

回答

82

我有一個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; 
} 
+24

如果枚舉值本身包含逗號,則此解決方案將中斷。 – 2012-12-07 22:53:01

+2

此解決方案適用於codeigniter https:// github。com/thiswolf/codeigniter-enum-select-boxes – 2013-07-07 16:28:47

+3

PHP Version:$ type = $ this-> mysql-> select(「SHOW COLUMNS FROM $ table WHERE Field ='$ field'」)[0] [「Type」] ; – 2014-08-27 09:14:54

24

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

我只是想添加什麼jasonbar說,查詢就像當:

SHOW columns FROM table 

如果你得到的結果作爲陣列它將看起來像這樣:

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

其中[n]和[文本]給出相同的值。
在我找到的任何文檔中都沒有記錄。很高興知道還有什麼。

35

您可以通過查詢它像這樣得到的數值:

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

從那裏,你需要把它轉換成一個數組:

  • EVAL直接到一個數組,如果你」 (儘管MySQL的單引號轉義可能不兼容),或者
  • $ options_array = str_getcsv($ options,',',「'」)可能會起作用(如果改變子字符串以跳過開始和結束括號) ,或
  • 正則表達式
2
$row = db_fetch_object($result); 
    if($row){ 
    $type = $row->Type; 
    preg_match_all("/'([^']+)'/", $type, $matches,PREG_PATTERN_ORDER); 
    return $matches[1]; 


} 
8

可以解析字符串,就好像它是一個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

+1

我給的例子並沒有告訴你如何從數據庫中的字段信息,但也有很多這方面的例子頁面上向您展示如何做到這一點。 – bashaus 2012-06-30 09:29:41

+2

'str_getcsv'只適用於PHP 5> = 5.3.0,您可以[包含此文件](http://pear.php.net/reference/PHP_Compat-latest/__filesource/fsource_PHP_Compat__PHP_Compat-1.6.0a3CompatFunctionstr_getcsv.php.html )如果你想在早期版本中獲得這個功能。 – Steve 2013-01-30 16:49:05

+1

這應該是正確的方法來處理它,因爲它會考慮字符串內部的轉義引號和逗號。 – 2016-12-09 10:33:25

2

試試這個

describe table columnname 

爲您提供所有關於該表的列的信息;

7

這是克里斯Komlenic的8 Reasons Why MySQL's ENUM Data Type Is Evil之一:

  4.獲取不同的ENUM成員名單是一種痛苦。

一個非常普遍的需求是使用數據庫中的可能值填充選擇框或下拉列表。就像這樣:

選擇顏色:

[ select box ]

如果這些值存儲在名爲「顏色」的參考表中,所有你需要的是:SELECT * FROM colors ...然後可以分析出動態生成下拉列表。您可以添加或更改參考表中的顏色,並且您的性感訂單將自動更新。真棒。

現在考慮邪惡的ENUM:你如何提取成員列表?您可以查詢表中的ENUM列以獲取DISTINCT值,但這隻會返回實際使用的值,並且會出現在表中,而不一定是所有可能的值。您可以使用腳本語言查詢INFORMATION_SCHEMA並將其從查詢結果中解析出來,但這不必要的複雜。實際上,我不知道任何優雅純粹的SQL方法來提取ENUM列的成員列表。

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

最終,由隔開,當枚舉值「枚舉()」僅僅是一個CSV字符串,所以解析它!

9

這就像很多上面的內容,但給你的結果沒有循環,並讓你想要你真的想要:一個簡單的數組產生選擇選項。

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] =>藍色 )

2

這裏是由帕特里克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; 

} 
2

笨適應版本的一些模型的方法:

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

這不提供問題的答案。要批評或要求作者澄清,在他們的帖子下留下評論 - 你總是可以評論你自己的帖子,一旦你有足夠的[聲譽](http://stackoverflow.com/help/whats-reputation),你會能夠[評論任何帖子](http://stackoverflow.com/help/privileges/comment)。 – worldofjr 2015-01-18 22:17:34

+0

你確定嗎?爲什麼? 這個函數的結果可以簡單地插入到像** form_dropdown **這樣的函數中... – 2015-01-20 00:50:24

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()'")); 
} 
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) 
2

可以在MySQL查詢使用語法GET枚舉可能值:

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

,你會得到的值,例如:枚舉( '男', '女')

這是例如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; 
} 
?> 
3

聽到的是對的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); 
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 
) 
0

我得到這樣枚舉值:

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

停止放:

陣列(2){ [0] => 串(4) 「BDBL」 [1] => string(7)「AB Bank」 }

0

在這個線程中的每個其他答案的問題是,他們都沒有正確解析枚舉中的字符串的所有特殊情況。

把我當成一個循環的最大特例是單引號,因爲它們自己編碼爲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 [email protected] AND [email protected]))); 
PREPARE stmt FROM @Q; 
EXECUTE stmt; 

附:爲了阻止任何人談論它,不,我不相信這種方法會導致SQL注入。

0

獲取可能值的列表已被詳細記錄,但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個字符,刪除尾部括號。

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