DB에서 가능한 열거 형 값으로 드롭 다운을 자동으로 채우고 싶습니다. 이것이 MySQL에서 가능합니까?
답변:
당신을위한 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 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;
}
이것은 위의 많은 것과 비슷하지만 루프가없는 결과를 제공하고 원하는 결과를 얻을 수 있습니다. 선택 옵션을 생성하기위한 간단한 배열입니다.
보너스 : 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] => 파란색)
이것은 Chris Komlenic의 MySQL의 ENUM 데이터 유형이 나쁜 8 가지 이유 중 하나입니다 .
4. 고유 한 ENUM 구성원 목록을 얻는 것은 고통 스럽습니다.
매우 일반적인 요구 사항은 데이터베이스에서 가능한 값으로 선택 상자 또는 드롭 다운 목록을 채우는 것입니다. 이렇게 :
색상 선택 :
[ select box ]
이러한 값이 'colors'라는 참조 테이블에 저장되어있는 경우 필요한 것은 다음과 같습니다.
SELECT * FROM colors
... 그런 다음 파싱하여 드롭 다운 목록을 동적으로 생성 할 수 있습니다. 참조 테이블에서 색상을 추가하거나 변경할 수 있으며 섹시한 주문 양식이 자동으로 업데이트됩니다. 대박.이제 사악한 ENUM을 고려하십시오. 멤버 목록을 어떻게 추출합니까? DISTINCT 값에 대해 테이블의 ENUM 열을 쿼리 할 수 있지만 모든 가능한 값 이 아니라 실제로 사용하고 테이블에있는 값만 반환 합니다. INFORMATION_SCHEMA를 쿼리하고 스크립팅 언어를 사용하여 쿼리 결과에서 구문 분석 할 수 있지만 불필요하게 복잡합니다. 실제로 ENUM 열의 멤버 목록을 추출하는 우아하고 순수한 SQL 방법을 모릅니다.
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
더 최신의 방법으로 나를 위해 일했습니다.
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);
다음은 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;
}
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
)
다음 과 같이 쿼리 할 때 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 ( '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;
}
?>
이 스레드의 다른 모든 답변의 문제는 열거 형 내의 문자열의 모든 특수 사례를 제대로 구문 분석하지 못한다는 것입니다.
나에게 루프를 던지는 가장 큰 특수 문자는 작은 따옴표였습니다. 두 개의 작은 따옴표로 함께 인코딩되기 때문입니다! 예를 들어 값 '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 주입으로 이어질 수 있다고 생각하지 않습니다.
가능한 값 목록을 가져 오는 방법은 잘 설명되어 있지만 괄호 안의 값을 반환하는 다른 답변을 확장 하여 쉼표로 구분 된 목록을 남겨두고 제거하고 싶었습니다. 그러면 언제든 분해 유형 함수를 사용할 수 있습니다. 배열을 얻는 데 필요합니다.
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";
}
이런 식으로 열거 형 값을 얻습니다.
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"}
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');
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')에 대해 작동하지 않습니다.