¿Cómo puedo obtener los posibles valores de enum en una base de datos MySQL?


Quiero rellenar mis desplegables con los posibles valores de enumeración de una base de datos automáticamente. ¿Es esto posible en MySQL?

 87
Author: Shamoon, 2010-02-28

22 answers

Tengo una versión codeigniter para ti. También elimina las comillas de los valores.

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
Author: Patrick Savalle,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-10-17 19:39:30

Puede obtener los valores consultándolo de la siguiente manera:

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

Desde allí tendrás que convertirlo en un array:

  • evalúe eso directamente en una matriz si es perezoso (aunque el escape de comillas simples de MySQL podría ser incompatible), o
  • possibly options_array = str_getcsv (options options, ',', "'") posiblemente funcionaría (si altera la subcadena para omitir los paréntesis de apertura y cierre), o
  • una expresión regular
 44
Author: Matthew,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-01-26 01:21:35

Referencia MySQL

Si desea determinar todos los posibles valores para una columna de enumeración, use MOSTRAR COLUMNAS DE tbl_name COMO enum_col y analizar la definición de enumeración en el Escriba la columna de la salida.

Usted querría algo como:

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

Esto le dará los valores citados. MySQL siempre devuelve estos encerrados entre comillas simples. Una comilla simple en el valor se escapa por una comilla simple. Probablemente puede llamar con seguridad a trim($val, "'") en cada uno de los elementos de la matriz. Usted querrá convertir '' en solo '.

Lo siguiente devolverá elementos del array trimm trimmedvals sin comillas:

$trimmedvals = array();
foreach($vals as $key => $value) {
$value=trim($value, "'");
$trimmedvals[] = $value;
}
 26
Author: jasonbar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-10-12 20:45:24

Esto es como muchos de los anteriores, pero le da el resultado sin bucles, Y obtiene lo que realmente desea: una matriz simple para generar opciones select.

BONUS: Funciona tanto para el CONJUNTO como para los tipos de campos de ENUMERACIÓN.

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

Op option_array: Matriz ( [0] => rojo [1] => verde [2] => azul )

 9
Author: Phreditor,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-07-29 00:26:56

Puede analizar la cadena como si fuera una cadena CSV (Valor Separado por comas). PHP tiene una gran función integrada llamada str_getcsv que convierte una cadena CSV en una matriz.

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

Esto debería darte algo similar a lo siguiente:

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

Este método también le permite tener comillas simples en sus cadenas (observe el uso de dos comillas simples):

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

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

Para obtener más información sobre la función str_getcsv, consulte el PHP manual: http://uk.php.net/manual/en/function.str-getcsv.php

 8
Author: bashaus,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-06-30 09:28:17

Esta es una de las 8 Razones de Chris Komlenic Por las que el Tipo de datos ENUM de MySQL es Malvado :

4. Obtener una lista de los distintos miembros de ENUM es una molestia.

Una necesidad muy común es llenar un cuadro de selección o lista desplegable con los posibles valores de la base de datos. Así:

Seleccione el color:

[ select box ]

Si estos valores se almacenan en una tabla de referencia llamada 'colors', todo lo que necesita es: SELECT * FROM colors ...que puede luego se analizará para generar dinámicamente la lista desplegable. Puede agregar o cambiar los colores en la tabla de referencia, y sus formularios de pedido sexy se actualizarán automáticamente. Impresionante.

Ahora consideremos el ENUM malvado: ¿cómo se extrae la lista de miembros? Puede consultar la columna ENUMERACIÓN en su tabla para valores DISTINTOS, pero eso solo devolverá los valores que realmente se usan y están presentes en la tabla, no necesariamente todos los valores posibles. Puede consultar INFORMATION_SCHEMA y analizarlos del resultado de la consulta con un lenguaje de scripting, pero eso es innecesariamente complicado. De hecho, no conozco ninguna forma elegante y puramente SQL de extraer la lista de miembros de una columna de enumeración.

 8
Author: eggyal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-06-17 20:10:00

Una forma más actualizada de hacerlo, esto funcionó para mí:

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 última instancia, los valores de enum cuando se separan de" enum () " es solo una cadena CSV, ¡así que analícela como tal!

 6
Author: Scott Krelo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-12-30 21:38:12

Aquí está para 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
Author: Сергей Алексанян,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-02 13:23:03

Simplemente quiero agregar a lo que jasonbar dice, al preguntar como:

SHOW columns FROM table

Si obtiene el resultado como una matriz, se verá así:

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

Donde [n] y [text] dan el mismo valor.
Realmente no se dice en ninguna documentación que he encontrado. Simplemente es bueno saber qué más hay allí.

 2
Author: JeroenEijkhof,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
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
Author: user774250,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-12-25 17:40:05

Prueba esto

describe table columnname

Te da toda la información sobre esa columna en esa tabla;

 2
Author: amitchhajer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-10-09 07:36:52

Aquí está la misma función dada por Patrick Savalle adaptada para el 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
Author: Anas Tiour,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-09-07 21:29:05

Codeigniter adaptando la versión como método de algún modelo:

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

Resultado:

array(2) {
    [0]=> string(13) "administrator"
    [1]=> string(8) "customer"
}
 2
Author: Андрій Глущенко,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-01-18 20:52:11

Puede usar esta sintaxis para obtener valores posibles enum en la CONSULTA MySQL:

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

Y obtienes valor, ejemplo : enum('Masculino','Femenino')

Este es el ejemplo de 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
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-01-25 07:03:52

Para Laravel esto funcionó:

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

Salida:

Array
(
[0] => Requested
[1] => Call Back
[2] => Busy
[3] => Not Reachable
[4] => Not Responding
)
 2
Author: Tousif Ahmed,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-02-15 08:07:41

El problema con cualquier otra respuesta en este hilo es que ninguna de ellas analiza correctamente todos los casos especiales de las cadenas dentro de la enumeración.

El mayor carácter de caso especial que me estaba lanzando para un bucle eran las comillas simples, ya que se codifican como 2 comillas simples juntas! Así, por ejemplo, una enumeración con el valor 'a' se codifica como enum('''a'''). Horrible, ¿verdad?

Bueno, la solución es usar MySQL para analizar los datos por usted!

Puesto que todos los demás son usando PHP en este hilo, eso es lo que usaré. A continuación se muestra el código completo. Lo explicaré después. El parámetro $FullEnumString contendrá toda la cadena de enumeración, extraída de cualquier método que desee usar de todas las demás respuestas. RunQuery() y FetchRow() (no asociativo) son sustitutos de sus métodos de acceso a bases de datos favoritos.

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

preg_match('/^enum\((.*)\)$/iD', $FullEnumString, $Matches) confirma que el valor de la enumeración coincide con lo que esperamos, es decir, "enum(".$STUFF.")" (sin nada antes o después). Si el preg_match falla, NULL es devolver.

Este preg_match también almacena la lista de cadenas, escapadas en sintaxis SQL extraña, en $Matches[1]. Así que a continuación, queremos ser capaces de obtener los datos reales de eso. Así que simplemente ejecuta "SELECT ".$Matches[1], ¡y tienes una lista completa de las cadenas en tu primer registro!

Así que simplemente saca ese registro con un FetchRow(RunQuery(...)) y listo.

Si quieres hacer todo esto en SQL, puedes usar lo siguiente{[15]]}

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.d. Para evitar que alguien diga algo al respecto, no, yo no creo que este método puede conducir a la inyección SQL.

 2
Author: Dakusan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-09-15 22:21:55

Todos ustedes usan algunos patrones de expresiones regulares extraños y complejos x)

Aquí está mi solución sin 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
Author: OraYa,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-05-03 13:41:13

Esto funcionará para mí:

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

Y luego

explode(',', $data)
 1
Author: marco,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-12-08 11:21:03

Obtengo los valores de enumeración de esta manera:

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

Ejecutando este sql tengo get: enum ('BDBL','AB Bank')

Entonces he filtrado solo valor usando el siguiente código:

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

Out put:

Array(2) { [0]=> cuerda (4) " BDBL" [1]=> cuerda (7) " Banco AB" }

 0
Author: Nahidul Hasan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-03-15 13:13:07

Para obtener la lista de posibles valores ha sido bien documentada, pero expandiendo otra respuesta que devolvía los valores entre paréntesis, quería eliminarlos dejándome con una lista separada por comas que luego me permitiría usar una función de tipo explode cada vez que necesitara obtener una matriz.

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

El SUBSTRING ahora comienza en el sexto carácter y usa una longitud que es 6 caracteres más corta que el total, eliminando el paréntesis final.

 0
Author: cchana,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-11-14 14:30:30

Para 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
Author: Anmol Shrivastava,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
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 ;

Ejemplo:

SELECT ENUM_VALUES('table_name', 'col_name');
 0
Author: Arman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-07-17 16:06:29