Bagaimana saya bisa mendapatkan nilai enum yang mungkin dalam database MySQL?

96

Saya ingin mengisi dropdown saya dengan enum kemungkinan nilai dari DB secara otomatis. Apakah ini mungkin di MySQL?

Shamoon
sumber

Jawaban:

97

Saya memiliki versi codeigniter untuk Anda. Itu juga menghapus kutipan dari nilai.

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;
}
Patrick Savalle
sumber
29
Solusi ini akan rusak jika nilai enum itu sendiri berisi koma.
Fo.
3
Solusi ini berfungsi pada codeigniter github.com/thiswolf/codeigniter-enum-select-boxes
You Know Nothing Jon Snow
3
Versi PHP: $ type = $ this-> mysql-> pilih ("SHOW COLUMNS FROM $ table WHERE Field = '$ field'") [0] ["Type"];
Alessandro.Vegna
untuk mengubah Nilai Jenis menjadi array menggunakan php saya membuat seperti ini: $ segment = str_replace ("'", "", $ row [0] [' Type ']); $ segment = str_replace ("enum", "", $ segment); $ segmen = str_replace ("(", "", $ segmen); $ segmen = str_replace (")", "", $ segmen); $ segmentList = meledak (',', $ segmen);
Gustavo Emmel
1
Saya telah menambahkan jawaban dengan cara bukti lengkap untuk mengekstrak semua nilai enum, tidak peduli karakter di dalamnya.
Dakusan
53

Anda bisa mendapatkan nilai dengan menanyakannya seperti ini:

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

Dari sana Anda harus mengubahnya menjadi array:

  • eval itu langsung ke dalam array jika Anda malas (meskipun pelolosan kutipan tunggal MySQL mungkin tidak kompatibel), atau
  • $ options_array = str_getcsv ($ options, ',', "'") mungkin akan berfungsi (jika Anda mengubah substring untuk melewati tanda kurung buka dan tutup), atau
  • ekspresi reguler
Matthew
sumber
31

Referensi MySQL

Jika Anda ingin menentukan semua kemungkinan nilai untuk kolom ENUM, gunakan SHOW COLUMNS FROM tbl_name LIKE enum_col dan parsing definisi ENUM di kolom Type pada output.

Anda menginginkan sesuatu seperti:

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

Ini akan memberi Anda nilai yang dikutip. MySQL selalu mengembalikan ini dalam tanda kutip tunggal. Kutipan tunggal dalam nilai dipisahkan oleh kutipan tunggal. Anda mungkin dapat memanggil trim($val, "'")setiap elemen array dengan aman. Anda pasti ingin mengubahnya ''menjadi file' .

Berikut ini akan mengembalikan item array $ trimmedvals tanpa tanda kutip:

$trimmedvals = array();
foreach($vals as $key => $value) {
$value=trim($value, "'");
$trimmedvals[] = $value;
}
jasonbar
sumber
11

Ini seperti banyak hal di atas, tetapi memberi Anda hasil tanpa loop, DAN membuat Anda benar-benar diinginkan: array sederhana untuk menghasilkan opsi pilih.

BONUS: Ini berfungsi untuk SET serta jenis bidang 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] => red [1] => green [2] => blue)

Phreditor
sumber
10

Ini adalah salah satu dari 8 Alasan Chris Komlenic Mengapa Tipe Data ENUM MySQL Itu Jahat :

 4. Mendapatkan daftar anggota ENUM yang berbeda sangat merepotkan.

Kebutuhan yang sangat umum adalah mengisi kotak-pilih atau daftar drop-down dengan kemungkinan nilai dari database. Seperti ini:

Pilih warna:

[ select box ]

Jika nilai-nilai ini disimpan dalam tabel referensi bernama 'warna', yang Anda butuhkan hanyalah: SELECT * FROM colors... yang kemudian dapat diurai untuk menghasilkan daftar tarik-turun secara dinamis. Anda dapat menambahkan atau mengubah warna di tabel referensi, dan formulir pesanan seksi Anda akan diperbarui secara otomatis. Hebat.

Sekarang pertimbangkan ENUM jahat: bagaimana Anda mengekstrak daftar anggota? Anda bisa membuat kueri kolom ENUM di tabel Anda untuk nilai yang berbeda tetapi itu hanya akan mengembalikan nilai yang benar-benar digunakan dan ada dalam tabel , tidak harus semua nilai yang mungkin. Anda bisa membuat kueri INFORMATION_SCHEMA dan menguraikannya dari hasil kueri dengan bahasa skrip, tapi itu terlalu rumit. Sebenarnya, saya tidak tahu cara SQL yang elegan dan murni untuk mengekstrak daftar anggota kolom ENUM.

telur
sumber
9

Anda dapat mengurai string tersebut seolah-olah itu adalah string CSV (Comma Separated Value). PHP memiliki fungsi built-in yang disebut str_getcsv yang mengubah string CSV menjadi array.

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

Ini akan memberi Anda sesuatu yang mirip dengan berikut ini:

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

Metode ini juga memungkinkan Anda untuk memiliki tanda kutip tunggal di string Anda (perhatikan penggunaan dua tanda kutip tunggal):

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

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

Untuk informasi lebih lanjut tentang fungsi str_getcsv, periksa manual PHP: http://uk.php.net/manual/en/function.str-getcsv.php

bashaus
sumber
1
Contoh yang saya berikan tidak menunjukkan kepada Anda bagaimana mendapatkan informasi lapangan dari database, tetapi ada banyak contoh di halaman ini untuk menunjukkan kepada Anda bagaimana melakukannya.
bashaus
2
str_getcsvhanya berfungsi di PHP 5> = 5.3.0, Anda dapat menyertakan file ini jika Anda ingin mendapatkan fungsionalitas ini di versi sebelumnya.
Steve
1
Ini harus menjadi cara yang benar untuk menanganinya karena menganggap kutipan dan koma yang lolos di dalam string.
Kristoffer Sall-Storgaard
1
Solusi brilian, menghemat waktu;)
John
6

Cara yang lebih mutakhir untuk melakukannya, ini berhasil untuk saya:

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

Pada akhirnya, nilai enum saat dipisahkan dari "enum ()" hanyalah string CSV, jadi uraikan seperti itu!

Scott Krelo
sumber
5

di sini untuk 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);
Сергей Алексанян
sumber
4

Berikut adalah fungsi yang sama yang diberikan oleh Patrick Savalle yang diadaptasi untuk kerangka kerja 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;

}
Anas Tiour
sumber
3

Untuk Laravel ini berhasil:

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

Keluaran:

Array
(
[0] => Requested
[1] => Call Back
[2] => Busy
[3] => Not Reachable
[4] => Not Responding
)
Kapten Sparrow
sumber
Sempurna, terima kasih. Ini bekerja paling baik untuk saya (Laravel 6)
Hondaman900
2

Saya hanya ingin menambahkan apa yang dikatakan jasonbar , saat menanyakan seperti:

SHOW columns FROM table

Jika Anda mendapatkan hasilnya sebagai array, akan terlihat seperti ini:

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

Dimana [n] dan [teks] memberikan nilai yang sama.
Tidak benar-benar diceritakan dalam dokumentasi yang saya temukan. Cukup baik untuk mengetahui apa lagi yang ada di sana.

JeroenEijkhof
sumber
2
$row = db_fetch_object($result);
     if($row){
     $type = $row->Type;
     preg_match_all("/'([^']+)'/", $type, $matches,PREG_PATTERN_ORDER );
     return $matches[1];


}
pengguna774250
sumber
2

coba ini

describe table columnname

memberi Anda semua informasi tentang kolom itu di tabel itu;

amitchhajer
sumber
2

Versi adaptasi Codeigniter sebagai metode dari beberapa model:

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

Hasil:

array(2) {
    [0]=> string(13) "administrator"
    [1]=> string(8) "customer"
}
Андрій Глущенко
sumber
Ini tidak memberikan jawaban atas pertanyaan. Untuk mengkritik atau meminta klarifikasi dari seorang penulis, tinggalkan komentar di bawah kiriman mereka - Anda selalu dapat mengomentari kiriman Anda sendiri, dan setelah Anda memiliki reputasi yang memadai, Anda akan dapat mengomentari kiriman apa pun .
worldofjr
Apakah kamu yakin Mengapa? Hasil dari fungsi ini dapat disisipkan dengan mudah ke dalam fungsi seperti form_dropdown ...
Андрій Глущенко
2

Kalian semua menggunakan beberapa pola regex yang aneh dan kompleks x)

Inilah solusi saya tanpa 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()'"));
}
OraYa
sumber
2

Anda dapat menggunakan sintaks ini untuk mendapatkan kemungkinan nilai enum di MySQL QUERY:

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

dan Anda mendapatkan nilai, contoh: enum ('Pria', 'Wanita')

ini adalah contoh 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;
}
?>

sumber
2

Masalah dengan setiap jawaban lain di utas ini adalah tidak satupun dari mereka yang mengurai dengan benar semua kasus khusus dari string dalam enum.

Karakter kasus khusus terbesar yang membuat saya berputar-putar adalah tanda kutip tunggal, karena mereka dikodekan sendiri sebagai 2 tanda kutip tunggal bersama-sama! Jadi, misalnya, enum dengan nilai 'a'dikodekan sebagai enum('''a'''). Mengerikan, bukan?

Nah, solusinya adalah dengan menggunakan MySQL untuk mengurai data untuk Anda!

Karena semua orang menggunakan PHP di utas ini, itulah yang akan saya gunakan. Berikut kode lengkapnya. Saya akan menjelaskannya setelah. Parameter $FullEnumStringakan menampung seluruh string enum, diekstrak dari metode apa pun yang ingin Anda gunakan dari semua jawaban lainnya. RunQuery()dan FetchRow()(non asosiatif) adalah stand-in untuk metode akses DB favorit Anda.

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

preg_match('/^enum\((.*)\)$/iD', $FullEnumString, $Matches)mengonfirmasi bahwa nilai enum cocok dengan yang kita harapkan, yaitu, "enum(".$STUFF.")"(tanpa ada sebelum atau sesudah). Jika preg_match gagal, NULLdikembalikan.

Ini preg_matchjuga menyimpan daftar string, lolos dalam sintaks SQL aneh, di $Matches[1]. Jadi selanjutnya, kami ingin mendapatkan data yang sebenarnya dari itu. Jadi, Anda hanya menjalankan "SELECT ".$Matches[1], dan Anda memiliki daftar lengkap string di rekaman pertama Anda!

Jadi tarik saja rekaman itu dengan a FetchRow(RunQuery(...))dan selesai.

Jika Anda ingin melakukan semua ini dalam SQL, Anda dapat menggunakan yang berikut ini

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 Untuk mencegah siapa pun mengatakan sesuatu tentang itu, tidak, saya tidak percaya metode ini dapat menyebabkan injeksi SQL.

Dakusan
sumber
Solusi bagus! Tentu saja, ini bukan injeksi SQL, karena kami mengambil nilai dari skema DB kami sendiri.
Terales
Terima kasih atas pendekatannya. Saya mendapatkan nilai berulang dalam larik seperti ini {"building_regulations": "building_regulations", "0": "building_regulations", "list_of_owners": "list_of_owners", "1": "list_of_owners"}. Ada ide mengapa? (Bekerja dengan baik di phpmyadmin, tetapi ini adalah hasil ketika dijalankan menggunakan objek POD.)
Guney Ozsan
Ada 3 cara untuk menarik nilai dari baris mysql dari kueri di php. mysql_fetch_assoc menarik nilai dengan kunci yang tepat, mysql_fetch_row menarik nilai dengan kunci numerik, dan mysql_fetch_array dapat menarik nilai sebagai satu atau keduanya. Sepertinya pdo Anda menggunakan mysql_fetch_array untuk operasi ini. Harus ada cara untuk memberitahukannya agar tidak melakukan ini selama pengambilan.
Dakusan
Atau jawaban yang jauh lebih sederhana untuk masalah pdo Anda, jalankan saja array_unique, atau array_filter yang menghapus indeks numerik.
Dakusan
Luar biasa! Begitulah cara Anda membuat MySQL melakukan semua kerja keras.
Spencer Williams
2

Untuk mengambil daftar nilai yang mungkin telah didokumentasikan dengan baik, tetapi memperluas jawaban lain yang mengembalikan nilai dalam tanda kurung , saya ingin menghapusnya meninggalkan saya dengan daftar yang dipisahkan koma yang kemudian akan memungkinkan saya untuk menggunakan fungsi tipe meledak setiap kali saya dibutuhkan untuk mendapatkan sebuah array.

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

The SUBSTRINGsekarang dimulai pada karakter ke-6 dan menggunakan panjang yang 6 karakter lebih pendek dari total, menghilangkan tanda kurung trailing.

cchana.dll
sumber
1

ini akan berhasil untuk saya:

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

lalu

explode(',', $data)
marco
sumber
1

Untuk 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);
Anmol Shrivastava
sumber
1

Sungguh luar biasa bagaimana tidak ada di antara Anda yang mengira bahwa jika Anda menggunakan kolom enum, itu berarti nilai yang akan ditetapkan dikenal "a priori".

Oleh karena itu, jika nilai-nilai tersebut dikenal secara "a priori", cara terbaik untuk mengelolanya adalah melalui kelas Enum yang sangat sederhana.

Cium aturan dan simpan satu panggilan database.

<?php
class Genre extends \SplEnum {
 const male = "Male";
 const female = "Female";
}

http://it2.php.net/manual/en/class.splenum.php

Mindexperiment
sumber
0

Saya mendapatkan nilai enum dengan cara ini:

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

Menjalankan sql ini saya mendapatkan: enum ('BDBL', 'AB Bank')

maka saya telah memfilter nilai saja menggunakan kode berikut:

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

Keluaran:

larik (2) {[0] => string (4) "BDBL" [1] => string (7) "AB Bank"}

Nahidul Hasan
sumber
0
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 ;

Contoh:

SELECT ENUM_VALUES('table_name', 'col_name');
Arman
sumber
0

PILIH SUBSTRING (COLUMN_TYPE, 6, LENGTH (COLUMN_TYPE) - 6) SEBAGAI DARI information_schema.COLUMNS WHERE TABLE_NAME = 'Articles' AND COLUMN_NAME = 'status'

Tidak akan berfungsi untuk enum ('', 'X''XX')

Salvor Hardin
sumber
1
Jenis jawaban ini harus ada dalam komentar.
Rahul harinkhede
stack overflow cukup cerdas dan tidak mengizinkan saya berkomentar karena sistem reputasinya.
Salvor Hardin