Відповіді:
У мене для вас версія codeigniter. Він також вилучає лапки зі значень.
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;
}
Ви можете отримати значення, запитуючи це так:
SELECT SUBSTRING(COLUMN_TYPE,5)
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA='databasename'
AND TABLE_NAME='tablename'
AND COLUMN_NAME='columnname'
Звідти вам потрібно буде перетворити його в масив:
Якщо ви хочете визначити всі можливі значення для стовпця ENUM, використовуйте SHOW COLUMNS FROM tbl_name ПОДОБНО enum_col та проаналізуйте визначення ENUM у стовпці Type виводу.
Ви хотіли б щось на зразок:
$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]);
Це дасть вам вказані значення. MySQL завжди повертає їх, укладені в одинарні лапки. Одинарна лапка у значенні перекривається однією лапкою. Можливо, ви можете безпечно зателефонувати trim($val, "'")кожному з елементів масиву. Ви захочете перетворити ''на просто' .
Далі буде повернено елементи масиву $ trimmedvals без лапок:
$trimmedvals = array();
foreach($vals as $key => $value) {
$value=trim($value, "'");
$trimmedvals[] = $value;
}
Це схоже на багато з перерахованого вище, але дає вам результат без циклів І призводить до того, що ви дійсно хочете: простий масив для генерації вибраних параметрів.
БОНУС: Він працює як для SET, так і для типів полів 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: масив ([0] => червоний [1] => зелений [2] => синій)
Це одна з 8 причин Кріса Комленіча, чому тип даних ENUM MySQL є злим :
4. Отримати список різних членів ENUM - це проблема.
Найпоширенішою потребою є заповнити поле вибору або випадаючий список можливими значеннями з бази даних. Подобається це:
Виберіть колір:
[ select box ]Якщо ці значення зберігаються у довідковій таблиці з назвою "кольори", все, що вам потрібно, це:
SELECT * FROM colors..., які потім можна проаналізувати для динамічного створення спадного списку. Ви можете додати або змінити кольори в довідковій таблиці, і ваші сексуальні форми замовлення будуть автоматично оновлені. Дивовижно.А тепер розгляньте злий ENUM: як витягти список учасників? Ви можете запитати у стовпці ENUM у вашій таблиці значення DISTINCT, але це поверне лише ті значення, які фактично використовуються та представлені в таблиці , не обов’язково всі можливі значення. Ви можете надіслати запит до INFORMATION_SCHEMA та проаналізувати їх із результату запиту мовою сценаріїв, але це надмірно складно. Насправді, я не знаю жодного елегантного, суто SQL-способу вилучення списку членів стовпця ENUM.
Ви можете проаналізувати рядок так, ніби це рядок CSV (значення, відокремлене комами). PHP має чудову вбудовану функцію, яка називається str_getcsv, яка перетворює рядок CSV у масив.
// 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);
Це має дати щось подібне до наступного:
Array
(
[0] => blond
[1] => brunette
[2] => redhead
)
Цей метод також дозволяє вам мати одинарні лапки у ваших рядках (зверніть увагу на використання двох одинарних лапок):
$enum_or_set = "'blond','brunette','red''head'";
Array
(
[0] => blond
[1] => brunette
[2] => red'head
)
Щоб отримати додаткову інформацію про функцію str_getcsv, перевірте посібник PHP: http://uk.php.net/manual/en/function.str-getcsv.php
str_getcsvпрацює лише в PHP 5> = 5.3.0, ви можете включити цей файл, якщо хочете отримати цю функціональність у попередніх версіях.
Більш сучасний спосіб зробити це, це спрацювало для мене:
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;
}
Зрештою, значення enum, відокремлене від "enum ()", є лише рядком CSV, тому проаналізуйте його як таке!
ось для 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);
Ось та сама функція, яку дає Патрік Савалле, адаптована для фреймворку 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;
}
Я просто хочу додати до того, що говорить jasonbar , коли запитує , як:
SHOW columns FROM table
Якщо ви отримаєте результат як масив, він буде виглядати так:
array([0],[Field],[1],[Type],[2],[Null],[3],[Key],[4],[Default],[5],[Extra])
Де [n] та [text] дають однакове значення.
Насправді це не сказано в жодній документації, яку я знайшов. Просто добре знати, що там ще є.
$row = db_fetch_object($result);
if($row){
$type = $row->Type;
preg_match_all("/'([^']+)'/", $type, $matches,PREG_PATTERN_ORDER );
return $matches[1];
}
спробуйте це
describe table columnname
надає всю інформацію про цей стовпець у цій таблиці;
Версія адаптації Codeigniter як метод якоїсь моделі:
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];
}
Результат:
array(2) {
[0]=> string(13) "administrator"
[1]=> string(8) "customer"
}
Усі ви використовуєте якісь дивні та складні регулярні вирази x)
Ось моє рішення без 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()'"));
}
Ви можете використовувати цей синтаксис для отримання переліку можливих значень у MySQL QUERY:
$syntax = "SELECT COLUMN_TYPY FROM information_schema.`COLUMNS`
WHERE TABLE_NAME = '{$THE_TABLE_NAME}'
AND COLUMN_NAME = '{$THE_COLUMN_OF_TABLE}'";
і ви отримуєте значення, приклад: enum ('Чоловік', 'Жінка')
це приклад 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;
}
?>
Для Laravel це спрацювало:
$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);
Вихід:
Array
(
[0] => Requested
[1] => Call Back
[2] => Busy
[3] => Not Reachable
[4] => Not Responding
)
Проблема кожної іншої відповіді в цьому ланцюжку полягає в тому, що жоден з них не аналізує належним чином усі особливі випадки рядків у переліченні.
Найбільшим особливим символом, який кидав мене на цикл, були одинарні лапки, оскільки вони кодуються як 2 одинарні лапки разом! Так, наприклад, перелік зі значенням 'a'кодується як enum('''a'''). Жахливо, правда?
Ну, рішення полягає у використанні MySQL для синтаксичного аналізу даних!
Оскільки всі інші використовують PHP у цій темі, саме це я і буду використовувати. Далі - повний код. Поясню це після. Параметр $FullEnumStringбуде містити весь рядок переліку, витягнутий із будь-якого методу, який ви хочете використовувати з усіх інших відповідей. RunQuery()та FetchRow()(не асоціативні) є підставкою для ваших улюблених методів доступу до БД.
function GetDataFromEnum($FullEnumString)
{
if(!preg_match('/^enum\((.*)\)$/iD', $FullEnumString, $Matches))
return null;
return FetchRow(RunQuery('SELECT '.$Matches[1]));
}
preg_match('/^enum\((.*)\)$/iD', $FullEnumString, $Matches)підтверджує, що значення переліку відповідає тому, що ми очікуємо, тобто "enum(".$STUFF.")"(нічого ні до, ні після). Якщо preg_match не вдається, NULLповертається.
Тут preg_matchтакож зберігається список рядків, екранованих у дивному синтаксисі SQL, у $Matches[1]. Отже, ми хочемо отримати з цього реальні дані. Отже, ви просто запускаєтесь "SELECT ".$Matches[1], і у вас є повний список рядків у вашому першому записі!
Тож просто витягніть цей запис за допомогою a, FetchRow(RunQuery(...))і все готово.
Якщо ви хочете зробити все це в SQL, ви можете використовувати наступне
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 Щоб запобігти тому, щоб хтось щось про це сказав, ні, я не вважаю, що цей метод може призвести до введення SQL.
Щоб отримати список можливих значень, було добре задокументовано, але, розширюючи іншу відповідь, яка повертала значення в дужках , я хотів їх викреслити, залишаючи мені список, відокремлений комами, який тоді дозволив би мені використовувати функцію типу вибуху щоразу, коли я потрібно отримати масив.
SELECT
SUBSTRING(COLUMN_TYPE, 6, LENGTH(COLUMN_TYPE) - 6) AS val
FROM
information_schema.COLUMNS
WHERE
TABLE_NAME = 'articles'
AND
COLUMN_NAME = 'status'
SUBSTRINGТепер починається на 6 - й символ і використовує довжину, 6 символів коротше , ніж загальна кількість, видаляючи косу дужку.
Для 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);
Надзвичайно, як ніхто з вас не думав, що якщо ви використовуєте поле переліку, це означає, що значення, які слід призначити, відомі "апріорі".
Тому, якщо значення відомі "апріорі", найкращі способи управління ними здійснюються за допомогою дуже простого класу Enum.
Поцілуйте правило та збережіть один дзвінок до бази даних.
<?php
class Genre extends \SplEnum {
const male = "Male";
const female = "Female";
}
Я отримую значення enum таким чином:
SELECT COLUMN_TYPE
FROM information_schema.`COLUMNS`
WHERE TABLE_NAME = 'tableName'
AND COLUMN_NAME = 'columnName';
Запустивши цей sql, я маю get: enum ('BDBL', 'AB Bank')
тоді я відфільтрував лише значення, використовуючи такий код:
preg_match("/^enum\(\'(.*)\'\)$/", $type, $matches);
$enum = explode("','", $matches[1]);
var_dump($enum) ;
Вийшов:
масив (2) {[0] => рядок (4) "BDBL" [1] => рядок (7) "АБ Банк"}
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 ;
Приклад:
SELECT ENUM_VALUES('table_name', 'col_name');
ВИБЕРІТЬ СУБСТРИНГ (COLUMN_TYPE, 6, LENGTH (COLUMN_TYPE) - 6) ЯК val FROM information_schema.COLUMNS WHERE TABLE_NAME = 'articles' AND COLUMN_NAME = 'status'
Не працює для enum ('', 'X''XX')