MySQL 데이터베이스에서 가능한 열거 형 값을 얻으려면 어떻게해야합니까?


96

DB에서 가능한 열거 형 값으로 드롭 다운을 자동으로 채우고 싶습니다. 이것이 MySQL에서 가능합니까?

답변:


97

당신을위한 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;
}

29
열거 형 값 자체에 쉼표가 포함되어 있으면이 솔루션이 중단됩니다.
Fo.


3
PHP 버전 : $ type = $ this-> mysql-> select ( "$ table WHERE Field = '$ field'") [0] [ "Type"];
Alessandro.Vegna

PHP를 사용하여 Type Value를 배열로 변환하려면 다음과 같이 만들었습니다. $ segments = str_replace ( " '", "", $ row [0] ['Type ']); $ segments = str_replace ( "enum", "", $ segments); $ segments = str_replace ( "(", "", $ segments); $ segments = str_replace ( ")", "", $ segments); $ segmentList = explode ( ',', $ segments);
Gustavo Emmel 2017

1
내부의 문자에 관계없이 모든 열거 형 값을 추출하는 완전한 증명 방법으로 답변 을 추가 했습니다.
Dakusan

53

다음과 같이 쿼리하여 값을 가져올 수 있습니다.

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

거기에서 배열로 변환해야합니다.

  • 게으른 경우 배열로 직접 평가하십시오 (MySQL의 작은 따옴표 이스케이프는 호환되지 않을 수 있음).
  • $ options_array = str_getcsv ($ options, ',', " '") 아마도 작동 할 것입니다 (여는 괄호와 닫는 괄호를 건너 뛰도록 하위 문자열을 변경 한 경우) 또는
  • 정규식

31

MySQL 참조

ENUM 열에 대해 가능한 모든 값을 확인하려면 SHOW COLUMNS FROM tbl_name LIKE enum_col을 사용하고 출력의 Type 열에서 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;
}

11

이것은 위의 많은 것과 비슷하지만 루프가없는 결과를 제공하고 원하는 결과를 얻을 수 있습니다. 선택 옵션을 생성하기위한 간단한 배열입니다.

보너스 : 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] => 파란색)


10

이것은 Chris Komlenic의 MySQL의 ENUM 데이터 유형이 나쁜 8 가지 이유 중 하나입니다 .

 4. 고유 한 ENUM 구성원 목록을 얻는 것은 고통 스럽습니다.

매우 일반적인 요구 사항은 데이터베이스에서 가능한 값으로 선택 상자 또는 드롭 다운 목록을 채우는 것입니다. 이렇게 :

색상 선택 :

[ select box ]

이러한 값이 'colors'라는 참조 테이블에 저장되어있는 경우 필요한 것은 다음과 같습니다. SELECT * FROM colors... 그런 다음 파싱하여 드롭 다운 목록을 동적으로 생성 할 수 있습니다. 참조 테이블에서 색상을 추가하거나 변경할 수 있으며 섹시한 주문 양식이 자동으로 업데이트됩니다. 대박.

이제 사악한 ENUM을 고려하십시오. 멤버 목록을 어떻게 추출합니까? DISTINCT 값에 대해 테이블의 ENUM 열을 쿼리 할 수 ​​있지만 모든 가능한 값 이 아니라 실제로 사용하고 테이블에있는 값만 반환 합니다. INFORMATION_SCHEMA를 쿼리하고 스크립팅 언어를 사용하여 쿼리 결과에서 구문 분석 할 수 있지만 불필요하게 복잡합니다. 실제로 ENUM 열의 멤버 목록을 추출하는 우아하고 순수한 SQL 방법을 모릅니다.


9

CSV (Comma Separated Value) 문자열 인 것처럼 문자열을 구문 분석 할 수 있습니다. PHP에는 CSV 문자열을 배열로 변환하는 str_getcsv라는 훌륭한 내장 함수가 있습니다.

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


1
내가 제공 한 예제는 데이터베이스에서 필드 정보를 얻는 방법을 보여주지 않지만이 페이지에는 그 방법을 보여주는 많은 예제가 있습니다.
bashaus

2
str_getcsvPHP 5> = 5.3.0에서만 작동합니다 . 이전 버전에서이 기능을 사용하려면 이 파일을 포함 할 수 있습니다 .
스티브

1
이스케이프 된 따옴표와 문자열 내부의 쉼표를 고려하므로이 방법이 올바른 처리 방법이어야합니다.
Kristoffer Sall-Storgaard

1
탁월한 솔루션, 시간 절약;)
John

6

더 최신의 방법으로 나를 위해 일했습니다.

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 문자열이므로 그대로 구문 분석하십시오!


5

여기 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);

4

다음은 Laravel 프레임 워크에 적용한 Patrick Savalle이 제공 한 동일한 기능입니다.

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;

}

3

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
)

완벽합니다-감사합니다. 이것은 나에게 가장 잘 맞았습니다 (Laravel 6)
Hondaman900

2

다음 과 같이 쿼리 할 때 jasonbar가 말하는 내용을 추가하고 싶습니다.

SHOW columns FROM table

결과를 배열로 얻으면 다음과 같이 보일 것입니다.

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

여기서 [n]과 [text]는 동일한 값을 제공합니다.
내가 찾은 문서에서 실제로 말하지 않았습니다. 다른 것이 무엇인지 아는 것만으로도 좋습니다.


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


}

2

이 시도

describe table columnname

해당 테이블의 해당 열에 대한 모든 정보를 제공합니다.


2

일부 모델의 방법으로 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"
}

이것은 질문에 대한 답을 제공하지 않습니다. 작성자에게 비평이나 설명을 요청하려면 게시물 아래에 댓글을 남겨주세요. 언제든지 자신의 게시물에 댓글을 달 수 있으며, 충분한 평판얻으면 모든 게시물댓글 수 있습니다 .
worldofjr

확실합니까? 왜? 이 함수의 결과는 단순히 같은 기능에 삽입 할 수있는 form_dropdown ...
Андрій Глущенко에게

2

여러분 모두 이상하고 복잡한 정규식 패턴을 사용합니다. 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()'"));
}

2

이 구문을 사용하여 MySQL QUERY에서 가능한 열거 형 값을 얻을 수 있습니다.

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

그리고 당신은 값을 얻습니다. 예 : enum ( 'Male', 'Female')

이것은 예제 구문 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;
}
?>

2

이 스레드의 다른 모든 답변의 문제는 열거 형 내의 문자열의 모든 특수 사례를 제대로 구문 분석하지 못한다는 것입니다.

나에게 루프를 던지는 가장 큰 특수 문자는 작은 따옴표였습니다. 두 개의 작은 따옴표로 함께 인코딩되기 때문입니다! 예를 들어 값 'a'이 있는 열거 형 은 enum('''a'''). 끔찍 하죠?

음, 해결책은 MySQL을 사용하여 데이터를 구문 분석하는 것입니다!

다른 모든 사람들이이 스레드에서 PHP를 사용하고 있기 때문에 이것이 제가 사용할 것입니다. 다음은 전체 코드입니다. 나중에 설명하겠습니다. 매개 변수 $FullEnumString는 다른 모든 답변에서 사용하려는 방법에서 추출한 전체 열거 문자열을 보유합니다. RunQuery()FetchRow()(비 연관)은 선호하는 DB 액세스 방법의 표준입니다.

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 값이 우리가 기대하는 것과 일치하는지 확인합니다 "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;

추신 : 누군가가 그것에 대해 말하지 못하도록 선점하기 위해이 방법이 SQL 주입으로 이어질 수 있다고 생각하지 않습니다.


훌륭한 솔루션! 물론 우리는 자체 DB 스키마에서 값을 가져 오기 때문에 SQL 삽입이 될 수 없습니다.
terales

접근 해 주셔서 감사합니다. 이 { "building_regulations": "building_regulations", "0": "building_regulations", "list_of_owners": "list_of_owners", "1": "list_of_owners"}와 같은 배열에서 반복되는 값을 얻고 있습니다. 이유는 무엇입니까? (물론 phpMyAdmin을 작동하지만, POD 개체를 사용하여 실행할 때이 결과입니다.)
귀 니 Ozsan

PHP의 쿼리에서 mysql 행의 값을 가져 오는 3 가지 방법이 있습니다. mysql_fetch_assoc는 적절한 키로 값을 가져오고 mysql_fetch_row는 숫자 키로 값을 가져오고 mysql_fetch_array는 값을 하나 또는 둘 다로 가져올 수 있습니다. pdo가이 작업에 mysql_fetch_array를 사용하는 것 같습니다. 가져 오는 동안이를 수행하지 않도록 지시하는 방법이 있어야합니다.
Dakusan

또는 pdo 문제에 대한 훨씬 더 간단한 대답은 array_unique 또는 숫자 인덱스를 제거하는 array_filter를 실행하십시오.
Dakusan

우수한! 이것이 MySQL이 모든 노력을 수행하도록 만드는 방법입니다.
Spencer Williams 19 년

2

가능한 값 목록을 가져 오는 방법은 잘 설명되어 있지만 괄호 안의 값을 반환하는 다른 답변을 확장 하여 쉼표로 구분 된 목록을 남겨두고 제거하고 싶었습니다. 그러면 언제든 분해 유형 함수를 사용할 수 있습니다. 배열을 얻는 데 필요합니다.

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 자 이상의 짧은 길이를 사용합니다.


1

이것은 나를 위해 작동합니다.

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)

1

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

1

열거 형 필드를 사용하는 경우 할당 할 값이 "선험적"이라는 것을 의미한다고 생각한 사람이 아무도 없다는 것은 놀라운 일입니다.

따라서 값이 "선험적으로"알려진 경우이를 관리하는 가장 좋은 방법은 매우 간단한 Enum 클래스를 사용하는 것입니다.

키스 규칙과 하나의 데이터베이스 호출을 저장합니다.

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

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


0

이런 식으로 열거 형 값을 얻습니다.

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] => string (4) "BDBL"[1] => string (7) "AB Bank"}


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 ;

예:

SELECT ENUM_VALUES('table_name', 'col_name');

0

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

enum ( '', 'X''XX')에 대해 작동하지 않습니다.


1
이러한 유형의 대답은 주석에 있어야합니다.
Rahul harinkhede

스택 오버플로는 매우 지능적이며 평판 시스템 때문에 언급 할 수 없습니다.
Salvor Hardin 19
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.