Intereting Posts
удалить дочерний узел в XML-файле с помощью php Множественные значения флажка не отображаются Можно ли захватить вывод эха в PHP? Удалить повторяющиеся значения из многомерного массива на основе определенного ключа юй. Доступ к функции из контроллера модулей Blade Laravel: как установить переменные в шаблоне? Правильный способ дезактивации ввода в MySQL с использованием PDO wordpress – вызов функции при отправке комментария Vim: показать подсказки или подпись функции для PHP preg_match_all соответствует нескольким строкам и получает значения, записанные в двойных кавычках PHP DOMDocument заменит дочерний элемент DOMElement на строку HTML Могу ли я «Mock» время в PHPUnit? Автоматическое разрешение Laravel ioc – работает от контроллера, но не от пользовательского класса обработка больших массивов с помощью array_diff Загрузка файла на php-сервере с устройства Android

Как я могу получить перечисление возможных значений в базе данных MySQL?

Я хочу автоматически заполнить свои выпадающие списки возможными значениями из базы данных. Возможно ли это в MySQL?

У меня для вас есть код. Он также удаляет кавычки из значений.

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' 

Оттуда вам нужно будет преобразовать его в массив:

  • eval, которые попадают непосредственно в массив, если вы ленивы (хотя сбой одиночной кавычки MySQL может быть несовместимым), или
  • $ options_array = str_getcsv ($ options, ',', "'"), возможно, сработает (если вы измените подстроку, чтобы пропустить открывающиеся и закрывающиеся круглые скобки), или
  • регулярное выражение

Справочник по MySQL

Если вы хотите определить все возможные значения для столбца ENUM, используйте SHOW COLUMNS FROM tbl_name LIKE enum_col и проанализируйте определение ENUM в столбце Тип вывода.

Вы хотели бы что-то вроде:

 $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] => синий)

Вы можете анализировать строку так, как если бы это была строка CSV (Comma Separated Value). 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

Это один из 8 причин, по которым Крис Комленич объясняет, почему тип данных ENUM от MySQL является злым :

4. Получение списка отдельных членов ENUM – это боль.

Очень часто необходимо заполнить выбранный или выпадающий список с возможными значениями из базы данных. Как это:

Выберите цвет:

[ select box ]

Если эти значения хранятся в справочной таблице с именем «colors», все, что вам нужно, это: SELECT * FROM colors …, который затем можно разобрать, чтобы динамически генерировать выпадающий список. Вы можете добавлять или изменять цвета в справочной таблице, и ваши сексуальные формы заказов будут автоматически обновляться. Потрясающие.

Теперь рассмотрим зло ENUM: как вы извлекаете список участников? Вы можете запросить столбец ENUM в таблице для значений DISTINCT, но это будет возвращать только те значения, которые фактически используются и присутствуют в таблице , а не все возможные значения. Вы можете запросить INFORMATION_SCHEMA и проанализировать их из результата запроса на языке сценариев, но это излишне сложно. На самом деле, я не знаю какого-либо изящного, чисто SQL-метода для извлечения списка членов столбца ENUM.

Более современный способ сделать это, это сработало для меня:

 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 ()», являются просто строкой 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); 

Я просто хочу добавить, что говорит Джейсонбар , когда вы спрашиваете :

 SHOW columns FROM table 

Если вы получите результат как массив, он будет выглядеть так:

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

Где [n] и [текст] дают одинаковое значение.
На самом деле не сказано ни в одной документации, которую я нашел. Просто хорошо знать, что еще есть.

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

попробуй это

 describe table columnname 

дает вам всю информацию об этом столбце в этой таблице;

Вот те же функции, которые дал Патрик Саваль, адаптированный для рамки 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; } 

Вариант адаптации 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" } 

Вы можете использовать этот синтаксис для получения возможных значений перечисления в 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; } ?> 

Все вы используете некоторые странные и сложные шаблоны регулярных выражений 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()'")); } 

это будет работать для меня:

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

а потом

 explode(',', $data) 

Для 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 ) 

Я получаю значения перечисления таким образом:

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

Запустив этот sql, я получил: enum («BDBL», «AB Bank»)

то я отфильтровал только значение, используя следующий код:

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

Вывод :

array (2) {[0] => строка (4) "BDBL" [1] => строка (7) "AB Bank"}

Проблема с любым другим ответом в этом потоке заключается в том, что ни один из них не должен правильно анализировать все особые случаи строк в перечислении.

Самый большой особый случайный характер, который бросал меня за цикл, заключался в одинарных кавычках, поскольку они были закодированы как две одиночные кавычки вместе! Так, например, перечисление со значением '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] , и у вас есть полный список строк в вашей первой записи!

Так что просто вытащите эту запись с помощью 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-инъекции.

Чтобы получить список возможных значений, был хорошо документирован, но, расширяя еще один ответ, который возвращал значения в скобках , я хотел их разбить, оставив мне список, разделенный запятыми, который затем позволит мне использовать функцию типа explode всякий раз, когда я необходимо получить массив.

 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 символов короче, чем сумма, удаляя скользящую скобку.