Comment puis-je obtenir des valeurs possibles enum dans une base de données MySQL?

Je veux remplir mes listes déroulantes avec l'énumération des valeurs possibles d'une base de données automatiquement. Est-ce possible dans MySQL?

87
demandé sur Shamoon 2010-02-28 07:09:44

22 réponses

J'ai une version codeigniter pour vous. Il supprime également les guillemets des valeurs.

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;
}
88
répondu Patrick Savalle 2014-10-17 19:39:30

Vous pouvez obtenir les valeurs en interrogeant comme ceci:

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

À Partir de là, vous devrez le convertir en un tableau:

  • eval cela directement dans un tableau si vous êtes paresseux (bien que L'échappement de citation unique de MySQL puisse être incompatible), ou
  • $ options_array = str_getcsv ($options, ',', "'") fonctionnerait probablement (si vous modifiez la sous-chaîne pour ignorer les parenthèses d'ouverture et de fermeture), ou
  • une expression régulière
44
répondu Matthew 2016-01-26 01:21:35

Référence MySQL

Si vous voulez déterminer tous les possibles valeurs pour une colonne ENUM, utilisez SHOW Colonnes de tbl_name comme enum_col et analyser la définition ENUM dans le Type colonne de la sortie.

, Vous voulez quelque chose comme:

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

Cela vous donnera les valeurs citées. MySQL renvoie toujours ceux-ci entre guillemets simples. Un guillemet unique dans la valeur est échappé par un guillemet unique. Vous pouvez probablement appeler en toute sécurité trim($val, "'") sur chacun des les éléments du tableau. Vous voulez convertir '' en seulement '.

Ce qui suit retournera les éléments du tableau $ trimmedvals sans guillemets:

$trimmedvals = array();
foreach($vals as $key => $value) {
$value=trim($value, "'");
$trimmedvals[] = $value;
}
26
répondu jasonbar 2015-10-12 20:45:24

C'est comme beaucoup de ce qui précède, mais vous donne le résultat sans boucles, et obtient que vous voulez vraiment: un tableau simple pour générer des options de sélection.

BONUS: cela fonctionne pour les types de champs SET et 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: Tableau ( [0] => rouge [1] => vert [2] => bleu )

9
répondu Phreditor 2014-07-29 00:26:56

Vous pouvez analyser la chaîne comme s'il s'agissait D'une chaîne CSV (valeur séparée par des virgules). PHP a une grande fonction intégrée appelée str_getcsv qui convertit une chaîne CSV en un tableau.

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

Cela devrait vous donner quelque chose de similaire à ce qui suit:

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

Cette méthode vous permet également d'avoir des guillemets simples dans vos cordes (notez l'utilisation de deux apostrophes):

$enum_or_set = "'blond','brunette','red''head'";

Array
(
    [0] => blond
    [1] => brunette
    [2] => red'head
)

Pour plus d'informations sur la fonction str_getcsv, consultez le PHP manuel: http://uk.php.net/manual/en/function.str-getcsv.php

8
répondu bashaus 2012-06-30 09:28:17

C'est L'une des 8 Raisons de Chris Komlenic pour lesquelles le type de données Enum de MySQL est maléfique :

4. Obtenir une liste de membres ENUM distincts est une douleur.

Un besoin très courant est de remplir une boîte de sélection ou une liste déroulante avec les valeurs possibles de la base de données. Comme ceci:

Sélectionner la couleur:

[ select box ]

Si ces valeurs sont stockées dans une table de référence nommée 'colors', tout ce dont vous avez besoin est: SELECT * FROM colors ...qui peut ensuite analysé afin de générer dynamiquement la liste déroulante. Vous pouvez ajouter ou modifier les couleurs dans le tableau de référence, et vos formulaires de commande sexy seront automatiquement mis à jour. Impressionnant.

Considérons maintenant l'énumération maléfique: comment extrayez-vous la liste des membres? Vous pouvez interroger la colonne ENUM dans votre table pour des valeurs distinctes mais cela ne retournera que des valeurs qui sont réellement utilisées et présentes dans la table , pas nécessairement toutes les valeurs possibles. Vous pouvez interroger INFORMATION_SCHEMA et analysez - les hors du résultat de la requête avec un langage de script, mais c'est inutilement compliqué. En fait, je ne connais aucun moyen élégant et purement SQL d'extraire la liste des membres d'une colonne ENUM.

8
répondu eggyal 2013-06-17 20:10:00

Une façon plus à jour de le faire, cela a fonctionné pour moi:

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

En fin de compte, les valeurs enum lorsqu'elles sont séparées de "enum ()" sont juste une chaîne CSV, alors analysez-la en tant que telle!

6
répondu Scott Krelo 2013-12-30 21:38:12

Voici pour 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);
5
répondu Сергей Алексанян 2018-04-02 13:23:03

Je veux simplement ajouter à ce quejasonbar dit, en interrogeant comme:

SHOW columns FROM table

Si vous obtenez le résultat comme un tableau, il ressemblera à ceci:

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

Où [N] et [text] donnent la même valeur.
Pas vraiment dit dans toute documentation que j'ai trouvé. Tout simplement bon de savoir quoi d'autre est là.

2
répondu JeroenEijkhof 2010-02-28 04:30:34
$row = db_fetch_object($result);
     if($row){
     $type = $row->Type;
     preg_match_all("/'([^']+)'/", $type, $matches,PREG_PATTERN_ORDER );
     return $matches[1];


}
2
répondu user774250 2011-12-25 17:40:05

Essayez ceci

describe table columnname

Vous donne toutes les informations sur cette colonne dans cette table;

2
répondu amitchhajer 2012-10-09 07:36:52

Voici la même fonction donnée par Patrick Savalle adaptée pour le framework 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
répondu Anas Tiour 2014-09-07 21:29:05

Codeigniter adapter la version comme méthode de certains modèles:

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

Résultat:

array(2) {
    [0]=> string(13) "administrator"
    [1]=> string(8) "customer"
}
2
répondu Андрій Глущенко 2015-01-18 20:52:11

Vous pouvez utiliser cette syntaxe pour obtenir des valeurs possibles enum dans la requête MySQL:

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

Et vous obtenez la valeur, exemple : enum ("Homme", "Femme")

Ceci est un exemple 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;
}
?>
2
répondu 2017-01-25 07:03:52

Pour Laravel cela a fonctionné:

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

Sortie:

Array
(
[0] => Requested
[1] => Call Back
[2] => Busy
[3] => Not Reachable
[4] => Not Responding
)
2
répondu Tousif Ahmed 2017-02-15 08:07:41

Le problème avec toutes les autres réponses dans ce thread est qu'aucun d'entre eux n'analyse correctement tous les cas spéciaux des chaînes dans l'énumération.

Le plus grand caractère de cas spécial qui me lançait pour une boucle était les guillemets simples, car ils sont eux-mêmes codés en 2 guillemets simples ensemble! Ainsi, par exemple, une énumération avec la valeur 'a' est codée comme enum('''a'''). Horrible, Non?

Eh bien, la solution est D'utiliser MySQL pour analyser les données pour vous!

Puisque tout le monde est en utilisant PHP dans ce fil, c'est ce que je vais utiliser. Voici le code complet. Je vais expliquer par la suite. Le paramètre $FullEnumString contiendra toute la chaîne enum, extraite de la méthode que vous souhaitez utiliser à partir de toutes les autres réponses. RunQuery() et FetchRow() (non associatif) sont des supports pour vos méthodes d'accès DB préférées.

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

preg_match('/^enum\((.*)\)$/iD', $FullEnumString, $Matches) confirme que la valeur enum correspond à ce que nous attendons, c'est-à-dire, "enum(".$STUFF.")" (avec rien avant ou après). Si le preg_match échoue, NULL est retourner.

Ce preg_match stocke également la liste des chaînes, échappées dans une syntaxe SQL étrange, dans $Matches[1]. Alors, la prochaine, nous voulons être en mesure d'obtenir les données. Si vous venez d'exécuter "SELECT ".$Matches[1], et vous avez une liste complète des chaînes dans votre premier enregistrement!

Donc, il suffit de sortir ce disque avec un FetchRow(RunQuery(...)) et vous avez terminé.

Si vous voulez faire tout cela en SQL, vous pouvez utiliser ce qui suit

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. pour empêcher quiconque de dire quelque chose à ce sujet, Non, Je ne croyez pas que cette méthode peut conduire à L'injection SQL.

2
répondu Dakusan 2017-09-15 22:21:55

Vous utilisez tous des motifs regex étranges et complexes x)

Voici ma solution sans 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
répondu OraYa 2016-05-03 13:41:13

Cela fonctionnera pour moi:

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__'

, puis

explode(',', $data)
1
répondu marco 2016-12-08 11:21:03

Je reçois des valeurs enum de cette façon:

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

En exécutant ce sql, j'ai get: enum ('BDBL','AB Bank')

Ensuite, j'ai filtré juste la valeur en utilisant le code suivant:

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

Sortie :

Tableau(2) { [0]=> chaîne(4) "BDBL" [1]=> chaîne (7) " AB Bank" }

0
répondu Nahidul Hasan 2017-03-15 13:13:07

Pour récupérer la liste des valeurs possibles a été bien documentée, mais en développant une autre réponse qui a renvoyé les valeurs entre parenthèses , je voulais les supprimer en me laissant avec une liste séparée par des virgules Qui me permettrait d'utiliser une fonction de type explode chaque fois que j'avais besoin d'obtenir un tableau.

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

Le SUBSTRING commence maintenant au 6ème caractère et utilise une longueur de 6 caractères plus courte que le total, supprimant la parenthèse finale.

0
répondu cchana 2017-11-14 14:30:30

Pour 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);
0
répondu Anmol Shrivastava 2018-05-09 16:46:51
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 ;

Exemple:

SELECT ENUM_VALUES('table_name', 'col_name');
0
répondu Arman 2018-07-17 16:06:29