Respuestas:
Tengo una versión de 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;
}
Puede obtener los valores consultando de esta manera:
SELECT SUBSTRING(COLUMN_TYPE,5)
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA='databasename'
AND TABLE_NAME='tablename'
AND COLUMN_NAME='columnname'
A partir de ahí, deberá convertirlo en una matriz:
Si desea determinar todos los valores posibles para una columna ENUM, use SHOW COLUMNS FROM tbl_name LIKE enum_col y analice la definición ENUM en la columna Tipo de la salida.
Querrías 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 cotizados. MySQL siempre los devuelve entre comillas simples. Una comilla simple en el valor se escapa por una comilla simple. Probablemente pueda llamar con seguridad trim($val, "'")
a cada uno de los elementos de la matriz. Querrás convertir ''
en solo '
.
Lo siguiente devolverá elementos de la matriz $ trimmedvals sin comillas:
$trimmedvals = array();
foreach($vals as $key => $value) {
$value=trim($value, "'");
$trimmedvals[] = $value;
}
Esto es como muchos de los anteriores, pero le brinda el resultado sin bucles, Y obtiene lo que realmente desea: una matriz simple para generar opciones de selección.
BONUS: funciona para los tipos de campo SET y 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: Array ([0] => rojo [1] => verde [2] => azul)
Esta es una de las 8 razones de Chris Komlenic por las que el tipo de datos ENUM de MySQL es malo :
4. Obtener una lista de distintos miembros ENUM es un fastidio.
Una necesidad muy común es llenar un cuadro de selección o una lista desplegable con posibles valores de la base de datos. Me gusta esto:
Seleccionar el color:
[ select box ]
Si estos valores se almacenan en una tabla de referencia llamada 'colores', todo lo que necesita es:
SELECT * FROM colors
... que luego se puede 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. Increíble.Ahora considere el malvado ENUM: ¿cómo se extrae la lista de miembros? Puede consultar la columna ENUM en su tabla para obtener valores DISTINCT, 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 a partir del resultado de la consulta con un lenguaje de secuencias de comandos, pero eso es innecesariamente complicado. De hecho, no conozco ninguna forma elegante, puramente SQL, de extraer la lista de miembros de una columna ENUM.
Puede analizar la cadena como si fuera una cadena CSV (valores separados por comas). PHP tiene una gran función incorporada 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 darle 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 manual de PHP: http://uk.php.net/manual/en/function.str-getcsv.php
str_getcsv
solo funciona en PHP 5> = 5.3.0, puede incluir este archivo si desea obtener esta funcionalidad en versiones anteriores.
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 enumeración cuando se separan de "enum ()" son solo una cadena CSV, ¡así que analícela como tal!
aquí es 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);
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;
}
Simplemente quiero agregar a lo que dice jasonbar , al consultar 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 [texto] dan el mismo valor.
Realmente no se dice en ninguna documentación que haya encontrado. Simplemente es bueno saber qué más hay.
$row = db_fetch_object($result);
if($row){
$type = $row->Type;
preg_match_all("/'([^']+)'/", $type, $matches,PREG_PATTERN_ORDER );
return $matches[1];
}
prueba esto
describe table columnname
le brinda toda la información sobre esa columna en esa tabla;
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"
}
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()'"));
}
Puede usar esta sintaxis para obtener valores posibles de enumeración en MySQL QUERY:
$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 ('Hombre', 'Mujer')
este es un 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;
}
?>
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
)
El problema con todas las demás respuestas en este hilo es que ninguno de ellos analiza correctamente todos los casos especiales de las cadenas dentro de la enumeración.
El personaje de caso especial más grande que me estaba lanzando por un bucle eran las comillas simples, ¡ya que están codificadas como 2 comillas simples juntas! Entonces, 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!
Dado que todos los demás usan 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 utilizar 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 enumeración coincide con lo que esperamos, es decir, "enum(".$STUFF.")"
(sin nada antes o después). Si preg_match falla, NULL
se devuelve.
Esto preg_match
también almacena la lista de cadenas, escapadas en una sintaxis SQL extraña, en formato $Matches[1]
. Entonces, a continuación, queremos poder obtener los datos reales de eso. ¡Así que simplemente corres "SELECT ".$Matches[1]
y tienes una lista completa de las cadenas en tu primer disco!
Así que saca ese disco con a FetchRow(RunQuery(...))
y listo.
Si quisiera hacer todo esto en SQL, podría usar lo siguiente
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;
PD: Para evitar que alguien diga algo al respecto, no, no creo que este método pueda conducir a una inyección SQL.
Para obtener la lista de valores posibles se ha documentado bien, 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 de explosión cada vez que necesario para 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.
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);
Es extraordinario cómo ninguno de ustedes ha pensado que si está utilizando un campo de enumeración significa que los valores a asignar se conocen "a priori".
Por tanto si los valores se conocen "a priori" la mejor forma de gestionarlos es a través de una clase Enum muy sencilla.
Besa la regla y guarda una llamada a la base de datos.
<?php
class Genre extends \SplEnum {
const male = "Male";
const female = "Female";
}
Obtengo 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')
luego he filtrado solo el valor usando el siguiente código:
preg_match("/^enum\(\'(.*)\'\)$/", $type, $matches);
$enum = explode("','", $matches[1]);
var_dump($enum) ;
Fuera puesto:
matriz (2) {[0] => cadena (4) "BDBL" [1] => cadena (7) "Banco AB"}
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');
SELECCIONE SUBSTRING (COLUMN_TYPE, 6, LENGTH (COLUMN_TYPE) - 6) AS val FROM information_schema.COLUMNS WHERE TABLE_NAME = 'articles' AND COLUMN_NAME = 'status'
No funcionaría para enum ('', 'X''XX')