Câu trả lời:
Tôi có một phiên bản mã cho bạn. Nó cũng tách các dấu ngoặc kép khỏi các giá trị.
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;
}
Bạn có thể lấy các giá trị bằng cách truy vấn nó như sau:
SELECT SUBSTRING(COLUMN_TYPE,5)
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA='databasename'
AND TABLE_NAME='tablename'
AND COLUMN_NAME='columnname'
Từ đó, bạn sẽ cần chuyển nó thành một mảng:
Nếu bạn muốn xác định tất cả các giá trị có thể có cho một cột ENUM, hãy sử dụng HIỂN THỊ CỘT TỪ tbl_name LIKE enum_col và phân tích cú pháp định nghĩa ENUM trong cột Loại của đầu ra.
Bạn sẽ muốn một cái gì đó như:
$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]);
Điều này sẽ cung cấp cho bạn các giá trị được trích dẫn. MySQL luôn trả về những giá trị này trong dấu ngoặc kép. Một dấu ngoặc kép trong giá trị được thoát bằng một dấu ngoặc kép. Bạn có thể gọi một cách an toàn trim($val, "'")
từng phần tử của mảng. Bạn sẽ muốn chuyển đổi ''
thành chỉ '
.
Phần sau sẽ trả về các mục mảng $ trimmedvals không có dấu ngoặc kép:
$trimmedvals = array();
foreach($vals as $key => $value) {
$value=trim($value, "'");
$trimmedvals[] = $value;
}
Điều này giống như nhiều cách ở trên, nhưng cung cấp cho bạn kết quả mà không có vòng lặp, VÀ đạt được điều bạn thực sự muốn: một mảng đơn giản để tạo các tùy chọn đã chọn.
BONUS: Nó hoạt động cho các loại trường SET cũng như 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)
Đây là một trong 8 lý do của Chris Komlenic tại sao Kiểu dữ liệu ENUM của MySQL là xấu :
4. Có được một danh sách các thành viên ENUM riêng biệt là một điều khó khăn.
Một nhu cầu rất phổ biến là điền vào một hộp chọn hoặc danh sách thả xuống với các giá trị có thể có từ cơ sở dữ liệu. Như thế này:
Chọn màu:
[ select box ]
Nếu các giá trị này được lưu trữ trong bảng tham chiếu có tên 'màu', tất cả những gì bạn cần là:
SELECT * FROM colors
... sau đó có thể phân tích cú pháp để tạo động danh sách thả xuống. Bạn có thể thêm hoặc thay đổi màu sắc trong bảng tham chiếu và các mẫu đơn đặt hàng sexy của bạn sẽ tự động được cập nhật. Tuyệt vời.Bây giờ hãy xem xét ENUM xấu xa: làm thế nào để bạn trích xuất danh sách thành viên? Bạn có thể truy vấn cột ENUM trong bảng của mình để tìm các giá trị DISTINCT nhưng điều đó sẽ chỉ trả về các giá trị thực sự được sử dụng và hiện diện trong bảng , không nhất thiết là tất cả các giá trị có thể có. Bạn có thể truy vấn INFORMATION_SCHEMA và phân tích cú pháp chúng ra khỏi kết quả truy vấn bằng ngôn ngữ kịch bản, nhưng điều đó phức tạp không cần thiết. Trên thực tế, tôi không biết bất kỳ cách SQL thanh lịch nào để trích xuất danh sách thành viên của một cột ENUM.
Bạn có thể phân tích cú pháp chuỗi như thể nó là một chuỗi CSV (Giá trị được phân tách bằng dấu phẩy). PHP có một hàm tích hợp tuyệt vời được gọi là str_getcsv để chuyển đổi một chuỗi CSV thành một mảng.
// 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);
Điều này sẽ cung cấp cho bạn một cái gì đó tương tự như sau:
Array
(
[0] => blond
[1] => brunette
[2] => redhead
)
Phương pháp này cũng cho phép bạn có các dấu nháy đơn trong chuỗi của mình (lưu ý việc sử dụng hai dấu nháy đơn):
$enum_or_set = "'blond','brunette','red''head'";
Array
(
[0] => blond
[1] => brunette
[2] => red'head
)
Để biết thêm thông tin về hàm str_getcsv, hãy xem hướng dẫn sử dụng PHP: http://uk.php.net/manual/en/ Chức năng.str-getcsv.php
str_getcsv
chỉ hoạt động trong PHP 5> = 5.3.0, bạn có thể bao gồm tệp này nếu bạn muốn có chức năng này trong các phiên bản trước đó.
Một cách làm việc cập nhật hơn, điều này phù hợp với tôi:
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;
}
Cuối cùng, các giá trị enum khi được phân tách từ "enum ()" chỉ là một chuỗi CSV, vì vậy hãy phân tích cú pháp nó như vậy!
đây là cho 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);
Đây là chức năng tương tự được đưa ra bởi Patrick Savalle được điều chỉnh cho khung 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;
}
Tôi chỉ muốn thêm vào những gì jasonbar nói, khi truy vấn như:
SHOW columns FROM table
Nếu bạn lấy kết quả dưới dạng một mảng, nó sẽ giống như sau:
array([0],[Field],[1],[Type],[2],[Null],[3],[Key],[4],[Default],[5],[Extra])
Trong đó [n] và [text] cho cùng giá trị.
Không thực sự được kể trong bất kỳ tài liệu nào tôi đã tìm thấy. Chỉ đơn giản là tốt để biết những gì khác ở đó.
$row = db_fetch_object($result);
if($row){
$type = $row->Type;
preg_match_all("/'([^']+)'/", $type, $matches,PREG_PATTERN_ORDER );
return $matches[1];
}
thử cái này
describe table columnname
cung cấp cho bạn tất cả thông tin về cột đó trong bảng đó;
Phiên bản điều chỉnh Codeigniter như một phương pháp của một số mô hình:
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];
}
Kết quả:
array(2) {
[0]=> string(13) "administrator"
[1]=> string(8) "customer"
}
Tất cả các bạn sử dụng một số mẫu regex phức tạp và kỳ lạ x)
Đây là giải pháp của tôi mà không có 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()'"));
}
Bạn có thể sử dụng cú pháp này để nhận các giá trị có thể có trong MySQL QUERY:
$syntax = "SELECT COLUMN_TYPY FROM information_schema.`COLUMNS`
WHERE TABLE_NAME = '{$THE_TABLE_NAME}'
AND COLUMN_NAME = '{$THE_COLUMN_OF_TABLE}'";
và bạn nhận được giá trị, ví dụ: enum ('Nam', 'Nữ')
đây là ví dụ về 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;
}
?>
Đối với Laravel, điều này đã hoạt động:
$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);
Đầu ra:
Array
(
[0] => Requested
[1] => Call Back
[2] => Busy
[3] => Not Reachable
[4] => Not Responding
)
Vấn đề với mọi câu trả lời khác trong chuỗi này là không có câu trả lời nào trong số chúng phân tích cú pháp đúng tất cả các trường hợp đặc biệt của các chuỗi trong enum.
Ký tự trường hợp đặc biệt lớn nhất khiến tôi phải quay lại là các dấu nháy đơn, vì chúng được mã hóa thành 2 dấu nháy đơn cùng nhau! Vì vậy, ví dụ, một enum có giá trị 'a'
được mã hóa thànhenum('''a''')
. Kinh khủng, phải không?
Tốt, giải pháp là sử dụng MySQL để phân tích dữ liệu cho bạn!
Vì mọi người khác đang sử dụng PHP trong chủ đề này, đó là những gì tôi sẽ sử dụng. Sau đây là mã đầy đủ. Tôi sẽ giải thích nó sau. Tham số $FullEnumString
sẽ chứa toàn bộ chuỗi enum, được trích xuất từ bất kỳ phương thức nào bạn muốn sử dụng từ tất cả các câu trả lời khác. RunQuery()
và FetchRow()
(không liên kết) là các đại diện cho các phương thức truy cập DB yêu thích của bạn.
function GetDataFromEnum($FullEnumString)
{
if(!preg_match('/^enum\((.*)\)$/iD', $FullEnumString, $Matches))
return null;
return FetchRow(RunQuery('SELECT '.$Matches[1]));
}
preg_match('/^enum\((.*)\)$/iD', $FullEnumString, $Matches)
xác nhận rằng giá trị enum khớp với những gì chúng ta mong đợi, có nghĩa là, "enum(".$STUFF.")"
(không có gì trước hoặc sau). Nếu preg_match không thành công,NULL
sẽ được trả về.
Điều này preg_match
cũng lưu trữ danh sách các chuỗi, được thoát theo cú pháp SQL lạ, trong $Matches[1]
. Vì vậy, tiếp theo, chúng tôi muốn có thể lấy được dữ liệu thực từ đó. Vì vậy, bạn chỉ cần chạy"SELECT ".$Matches[1]
và bạn có một danh sách đầy đủ các chuỗi trong bản ghi đầu tiên của bạn!
Vì vậy, chỉ cần kéo bản ghi đó ra với FetchRow(RunQuery(...))
và bạn đã hoàn tất.
Nếu bạn muốn thực hiện toàn bộ điều này trong SQL, bạn có thể sử dụng cách sau
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 Để ngăn bất kỳ ai nói điều gì đó về nó, không, tôi không tin rằng phương pháp này có thể dẫn đến việc đưa vào SQL.
Để tìm nạp danh sách các giá trị có thể đã được ghi chép đầy đủ, nhưng mở rộng trên một câu trả lời khác trả về các giá trị trong ngoặc đơn , tôi muốn loại bỏ chúng để lại cho tôi một danh sách được phân tách bằng dấu phẩy, sau đó sẽ cho phép tôi sử dụng hàm loại bùng nổ bất cứ khi nào tôi cần thiết để có được một mảng.
SELECT
SUBSTRING(COLUMN_TYPE, 6, LENGTH(COLUMN_TYPE) - 6) AS val
FROM
information_schema.COLUMNS
WHERE
TABLE_NAME = 'articles'
AND
COLUMN_NAME = 'status'
Hiện SUBSTRING
tại bắt đầu từ ký tự thứ 6 và sử dụng độ dài ngắn hơn tổng số 6 ký tự, loại bỏ dấu ngoặc đơn ở cuối.
Đối với 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);
Thật phi thường khi không ai trong số các bạn nghĩ rằng nếu bạn đang sử dụng một trường enum, điều đó có nghĩa là các giá trị được gán là "tiên nghiệm".
Do đó, nếu các giá trị được biết là "tiên nghiệm" thì cách tốt nhất để quản lý chúng là thông qua một lớp Enum rất đơn giản.
Quy tắc hôn và lưu một cuộc gọi cơ sở dữ liệu.
<?php
class Genre extends \SplEnum {
const male = "Male";
const female = "Female";
}
Tôi nhận các giá trị enum theo cách này:
SELECT COLUMN_TYPE
FROM information_schema.`COLUMNS`
WHERE TABLE_NAME = 'tableName'
AND COLUMN_NAME = 'columnName';
Chạy sql này tôi có: enum ('BDBL', 'AB Bank')
thì tôi chỉ lọc giá trị bằng mã sau:
preg_match("/^enum\(\'(.*)\'\)$/", $type, $matches);
$enum = explode("','", $matches[1]);
var_dump($enum) ;
Đưa ra:
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 ;
Thí dụ:
SELECT ENUM_VALUES('table_name', 'col_name');
CHỌN SUBSTRING (COLUMN_TYPE, 6, LENGTH (COLUMN_TYPE) - 6) AS val FROM information_schema.COLUMNS WHERE TABLE_NAME = 'posts' AND COLUMN_NAME = 'status'
Sẽ không hoạt động cho enum ('', 'X''XX')