Saya ingin mengisi dropdown saya dengan enum kemungkinan nilai dari DB secara otomatis. Apakah ini mungkin di MySQL?
Jawaban:
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;
}
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:
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;
}
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)
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.
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
str_getcsv
hanya berfungsi di PHP 5> = 5.3.0, Anda dapat menyertakan file ini jika Anda ingin mendapatkan fungsionalitas ini di versi sebelumnya.
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!
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);
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;
}
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
)
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.
$row = db_fetch_object($result);
if($row){
$type = $row->Type;
preg_match_all("/'([^']+)'/", $type, $matches,PREG_PATTERN_ORDER );
return $matches[1];
}
coba ini
describe table columnname
memberi Anda semua informasi tentang kolom itu di tabel itu;
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"
}
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()'"));
}
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;
}
?>
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 $FullEnumString
akan 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, NULL
dikembalikan.
Ini preg_match
juga 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.
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 SUBSTRING
sekarang dimulai pada karakter ke-6 dan menggunakan panjang yang 6 karakter lebih pendek dari total, menghilangkan tanda kurung trailing.
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);
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";
}
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"}
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');
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')