Antworten:
Ich habe eine Codeigniter-Version für Sie. Außerdem werden die Anführungszeichen aus den Werten entfernt.
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;
}
Sie können die Werte erhalten, indem Sie sie wie folgt abfragen:
SELECT SUBSTRING(COLUMN_TYPE,5)
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA='databasename'
AND TABLE_NAME='tablename'
AND COLUMN_NAME='columnname'
Von dort müssen Sie es in ein Array konvertieren:
Wenn Sie alle möglichen Werte für eine ENUM-Spalte ermitteln möchten, verwenden Sie SHOW COLUMNS FROM tbl_name LIKE enum_col und analysieren Sie die ENUM-Definition in der Spalte Type der Ausgabe.
Sie möchten so etwas wie:
$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]);
Dadurch erhalten Sie die angegebenen Werte. MySQL gibt diese immer in einfachen Anführungszeichen zurück. Ein einfaches Anführungszeichen im Wert wird durch ein einfaches Anführungszeichen maskiert. Sie können wahrscheinlich sicher trim($val, "'")jedes der Array-Elemente aufrufen . Sie möchten ''in nur konvertieren' .
Im Folgenden werden Array-Elemente mit $ trimmedvals ohne Anführungszeichen zurückgegeben:
$trimmedvals = array();
foreach($vals as $key => $value) {
$value=trim($value, "'");
$trimmedvals[] = $value;
}
Dies ist wie viele der oben genannten Schritte, liefert jedoch das Ergebnis ohne Schleifen UND bringt Sie dazu, dass Sie wirklich wollen: ein einfaches Array zum Generieren von Auswahloptionen.
BONUS: Es funktioniert sowohl für SET- als auch für ENUM-Feldtypen.
$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] => rot [1] => grün [2] => blau)
Dies ist einer der 8 Gründe von Chris Komlenic, warum der ENUM-Datentyp von MySQL böse ist :
4. Eine Liste mit verschiedenen ENUM-Mitgliedern zu erhalten, ist ein Schmerz.
Eine sehr häufige Notwendigkeit besteht darin, ein Auswahlfeld oder eine Dropdown-Liste mit möglichen Werten aus der Datenbank zu füllen. So was:
Wähle Farbe:
[ select box ]Wenn diese Werte in einer Referenztabelle mit dem Namen "Farben" gespeichert sind, benötigen Sie lediglich:
SELECT * FROM colors... die dann analysiert werden können, um die Dropdown-Liste dynamisch zu generieren. Sie können die Farben in der Referenztabelle hinzufügen oder ändern, und Ihre sexy Bestellformulare werden automatisch aktualisiert. Genial.Betrachten Sie nun die böse ENUM: Wie extrahieren Sie die Mitgliederliste? Sie können die ENUM-Spalte in Ihrer Tabelle nach DISTINCT-Werten abfragen, dies gibt jedoch nur Werte zurück, die tatsächlich verwendet werden und in der Tabelle vorhanden sind , nicht unbedingt alle möglichen Werte. Sie können INFORMATION_SCHEMA abfragen und sie mit einer Skriptsprache aus dem Abfrageergebnis analysieren, was jedoch unnötig kompliziert ist. Tatsächlich kenne ich keine elegante, rein SQL-Methode, um die Mitgliederliste einer ENUM-Spalte zu extrahieren.
Sie können die Zeichenfolge so analysieren, als wäre sie eine CSV-Zeichenfolge (Comma Separated Value). PHP hat eine großartige integrierte Funktion namens str_getcsv, die eine CSV-Zeichenfolge in ein Array konvertiert.
// 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);
Dies sollte Ihnen etwas Ähnliches wie das Folgende geben:
Array
(
[0] => blond
[1] => brunette
[2] => redhead
)
Mit dieser Methode können Sie auch einfache Anführungszeichen in Ihre Zeichenfolgen einfügen (beachten Sie die Verwendung von zwei einfachen Anführungszeichen):
$enum_or_set = "'blond','brunette','red''head'";
Array
(
[0] => blond
[1] => brunette
[2] => red'head
)
Weitere Informationen zur Funktion str_getcsv finden Sie im PHP-Handbuch: http://uk.php.net/manual/en/function.str-getcsv.php
str_getcsvfunktioniert nur in PHP 5> = 5.3.0. Sie können diese Datei einschließen, wenn Sie diese Funktionalität in früheren Versionen erhalten möchten.
Eine aktuellere Art, dies zu tun, funktionierte für mich:
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;
}
Letztendlich sind die Enum-Werte, wenn sie von "enum ()" getrennt werden, nur eine CSV-Zeichenfolge. Analysieren Sie sie also als solche!
hier ist für 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);
Hier ist die gleiche Funktion von Patrick Savalle für das Framework Laravel angepasst
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;
}
Ich möchte einfach hinzufügen, was Jasonbar sagt, wenn ich abfrage wie:
SHOW columns FROM table
Wenn Sie das Ergebnis als Array erhalten, sieht es folgendermaßen aus:
array([0],[Field],[1],[Type],[2],[Null],[3],[Key],[4],[Default],[5],[Extra])
Wobei [n] und [Text] den gleichen Wert angeben.
In keiner Dokumentation, die ich gefunden habe, wirklich erzählt. Einfach gut zu wissen, was es sonst noch gibt.
$row = db_fetch_object($result);
if($row){
$type = $row->Type;
preg_match_all("/'([^']+)'/", $type, $matches,PREG_PATTERN_ORDER );
return $matches[1];
}
Versuche dies
describe table columnname
gibt Ihnen alle Informationen zu dieser Spalte in dieser Tabelle;
Codeigniter, der die Version als Methode eines Modells anpasst:
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];
}
Ergebnis:
array(2) {
[0]=> string(13) "administrator"
[1]=> string(8) "customer"
}
Sie alle verwenden einige seltsame und komplexe Regex-Muster. X)
Hier ist meine Lösung ohne 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()'"));
}
Mit dieser Syntax können Sie mögliche Werte in MySQL QUERY abrufen:
$syntax = "SELECT COLUMN_TYPY FROM information_schema.`COLUMNS`
WHERE TABLE_NAME = '{$THE_TABLE_NAME}'
AND COLUMN_NAME = '{$THE_COLUMN_OF_TABLE}'";
und Sie erhalten Wert, Beispiel: enum ('Männlich', 'Weiblich')
Dies ist ein Beispiel für 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;
}
?>
Für Laravel funktionierte dies:
$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);
Ausgabe:
Array
(
[0] => Requested
[1] => Call Back
[2] => Busy
[3] => Not Reachable
[4] => Not Responding
)
Das Problem bei jeder anderen Antwort in diesem Thread ist, dass keiner von ihnen alle Sonderfälle der Zeichenfolgen innerhalb der Aufzählung richtig analysiert.
Das größte Sonderzeichen, das mich für eine Schleife geworfen hat, waren einfache Anführungszeichen, da sie selbst als zwei einfache Anführungszeichen zusammen codiert sind! So wird beispielsweise eine Aufzählung mit dem Wert 'a'als codiert enum('''a'''). Schrecklich, richtig?
Nun, die Lösung besteht darin, MySQL zu verwenden, um die Daten für Sie zu analysieren!
Da alle anderen in diesem Thread PHP verwenden, werde ich das verwenden. Es folgt der vollständige Code. Ich werde es später erklären. Der Parameter enthält $FullEnumStringdie gesamte Enum-Zeichenfolge, die aus einer beliebigen Methode extrahiert wurde, die Sie aus allen anderen Antworten verwenden möchten. RunQuery()und FetchRow()(nicht assoziativ) sind Stellvertreter für Ihre bevorzugten DB-Zugriffsmethoden.
function GetDataFromEnum($FullEnumString)
{
if(!preg_match('/^enum\((.*)\)$/iD', $FullEnumString, $Matches))
return null;
return FetchRow(RunQuery('SELECT '.$Matches[1]));
}
preg_match('/^enum\((.*)\)$/iD', $FullEnumString, $Matches)bestätigt, dass der Aufzählungswert mit dem übereinstimmt, was wir erwarten, dh "enum(".$STUFF.")"mit nichts vorher oder nachher). Wenn preg_match fehlschlägt, NULLwird zurückgegeben.
Hier wird preg_matchauch die Liste der Zeichenfolgen gespeichert, die in seltsamer SQL-Syntax maskiert sind $Matches[1]. Als nächstes wollen wir in der Lage sein, die realen Daten daraus zu gewinnen. Also rennst du einfach"SELECT ".$Matches[1] und haben eine vollständige Liste der Zeichenfolgen in Ihrem ersten Datensatz!
Ziehen Sie diese Platte einfach mit einem heraus FetchRow(RunQuery(...)) und Sie sind fertig.
Wenn Sie dies alles in SQL ausführen möchten, können Sie Folgendes verwenden
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;
PS Um zu verhindern, dass jemand etwas darüber sagt, nein, ich glaube nicht, dass diese Methode zu einer SQL-Injection führen kann.
Um die Liste der möglichen Werte abzurufen, wurde sie gut dokumentiert. Als Erweiterung einer anderen Antwort, die die Werte in Klammern zurückgab , wollte ich sie entfernen und eine durch Kommas getrennte Liste hinterlassen, in der ich jederzeit eine Explosionsfunktion verwenden kann benötigt, um ein Array zu bekommen.
SELECT
SUBSTRING(COLUMN_TYPE, 6, LENGTH(COLUMN_TYPE) - 6) AS val
FROM
information_schema.COLUMNS
WHERE
TABLE_NAME = 'articles'
AND
COLUMN_NAME = 'status'
Das SUBSTRINGbeginnt jetzt mit dem 6. Zeichen und verwendet eine Länge, die 6 Zeichen kürzer als die Gesamtzahl ist, wobei die nachfolgende Klammer entfernt wird.
Für 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 ist außergewöhnlich, wie keiner von Ihnen gedacht hat, dass wenn Sie ein Aufzählungsfeld verwenden, dies bedeutet, dass die zuzuweisenden Werte "a priori" bekannt sind.
Wenn die Werte "a priori" bekannt sind, können Sie sie am besten über eine sehr einfache Enum-Klasse verwalten.
Küssen Sie die Regel und speichern Sie einen Datenbankaufruf.
<?php
class Genre extends \SplEnum {
const male = "Male";
const female = "Female";
}
Ich erhalte Enum-Werte auf folgende Weise:
SELECT COLUMN_TYPE
FROM information_schema.`COLUMNS`
WHERE TABLE_NAME = 'tableName'
AND COLUMN_NAME = 'columnName';
Wenn ich diese SQL laufen lasse, bekomme ich: enum ('BDBL', 'AB Bank')
dann habe ich nur den Wert mit folgendem Code gefiltert:
preg_match("/^enum\(\'(.*)\'\)$/", $type, $matches);
$enum = explode("','", $matches[1]);
var_dump($enum) ;
Ausgabe :
Array (2) {[0] => String (4) "BDBL" [1] => String (7) "AB Bank"}
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 ;
Beispiel:
SELECT ENUM_VALUES('table_name', 'col_name');
SELECT SUBSTRING (COLUMN_TYPE, 6, LENGTH (COLUMN_TYPE) - 6) AS val FROM information_schema.COLUMNS WHERE TABLE_NAME = 'Artikel' UND COLUMN_NAME = 'Status'
Würde nicht für enum funktionieren ('', 'X''XX')