仅使用SQL获取MySQL枚举的值

时间:2013-06-13 14:34:42

标签: php mysql sql enums

在Web应用程序中,我需要使用MySQL枚举的所有可能值填充<select>

当我执行以下任何一项时:

SHOW COLUMNS FROM  mytable LIKE  'mycolumn';
SELECT COLUMN_TYPE FROM INFORMATION_SCHEMA.COLUMNS 
WHERE TABLE_NAME = 'mytable' AND COLUMN_NAME = 'mycolumn';
我总是以enum('valueA','valueB','valueC')结束。

我知道我可以用PHP解析它,但是它可以仅使用SQL来完成吗? 我需要这样的东西:

+-----------------+
| values          |
+-----------------+
| valueA          |
| valueB          |
| valueC          |
+-----------------+

3 个答案:

答案 0 :(得分:6)

这是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方式。

  

答案 1 :(得分:2)

虽然我同意大多数时候不使用枚举,但可以在单个SQL语句中使用: -

SELECT DISTINCT SUBSTRING_INDEX(SUBSTRING_INDEX(SUBSTRING(COLUMN_TYPE, 7, LENGTH(COLUMN_TYPE) - 8), "','", 1 + units.i + tens.i * 10) , "','", -1)
FROM INFORMATION_SCHEMA.COLUMNS
CROSS JOIN (SELECT 0 AS i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) units
CROSS JOIN (SELECT 0 AS i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) tens
WHERE TABLE_NAME = 'mytable' 
AND COLUMN_NAME = 'mycolumn'

这适用于最多包含100个可能值的枚举

答案 2 :(得分:0)

这是最简单的解决方案

$EnumColum = $mysqli->query(
  $link,
  "SELECT COLUMN_TYPE FROM INFORMATION_SCHEMA.COLUMNS
    WHERE TABLE_NAME = 'mrb_shipping_carriers' AND COLUMN_NAME = 'uspsServiceType'"
) or die("Error in " . ": " . __FILE__ . ": " . __LINE__);

$replace1 = preg_replace("/enum/", '',$EnumColum[0]['COLUMN_TYPE']);
$replace2 = preg_replace("/\(/", '',$replace1);
$replace3 = preg_replace("/\)/", '',$replace2);
$replace4 = preg_replace("/\'/", '',$replace3);
$newArray = explode(',',$replace4);
foreach($newArray as $value){
    echo $value . "\n<br>";
}