MySQL에서 ENUM 타입 칼럼에 멤버를 추가하려면 어떻게해야합니까?


157

MySQL 참조 매뉴얼은이를 수행하는 방법에 대한 명확한 예를 제공하지 않습니다.

국가를 추가해야하는 ENUM 유형의 국가 이름 열이 있습니다. 이것을 달성하기위한 올바른 MySQL 구문은 무엇입니까?

내 시도는 다음과 같습니다.

ALTER TABLE carmake CHANGE country country ENUM('Sweden','Malaysia');

내가 얻는 오류는 다음과 같습니다. ERROR 1265 (01000): Data truncated for column 'country' at row 1.

country열은 위의 문에서 ENUM 타입의 열입니다.

테이블 출력 생성 방법 :

mysql> SHOW CREATE TABLE carmake;
+---------+---------------------------------------------------------------------+
| Table   | Create Table
+---------+---------------------------------------------------------------------+
| carmake | CREATE TABLE `carmake` (
`carmake_id` tinyint(4) NOT NULL AUTO_INCREMENT,
`name` tinytext,
`country` enum('Japan','USA','England','Australia','Germany','France','Italy','Spain','Czech Republic','China','South Korea','India') DEFAULT NULL,
PRIMARY KEY (`carmake_id`),
KEY `name` (`name`(3))
) ENGINE=InnoDB AUTO_INCREMENT=49 DEFAULT CHARSET=latin1 |
+---------+---------------------------------------------------------------------+
1 row in set (0.00 sec)

carmake 출력 에서 고유 한 국가를 선택하십시오 .

+----------------+
| country        |
+----------------+
| Italy          |
| Germany        |
| England        |
| USA            |
| France         |
| South Korea    |
| NULL           |
| Australia      |
| Spain          |
| Czech Republic |
+----------------+

답변:


135
ALTER TABLE
    `table_name`
MODIFY COLUMN
    `column_name2` enum(
        'existing_value1',
        'existing_value2',
        'new_value1',
        'new_value2'
    )
NOT NULL AFTER `column_name1`;

7
대부분의 ALTER TABLE 명령은 전체 테이블을 완전히 다시 작성합니다. mysql은 enum으로 그렇게하지 않을만큼 영리합니까?
John

열거 형은 문자열 표현으로 멋진 정수입니다. 의미있는 오래된 값을 추가하기 때문에 항목을 끝에 추가하는 것이 좋습니다. 그러나 순서를 변경하거나 열거 형을 제거하면 해당 숫자가 정의되지 않습니다. (예 : 1 => 이탈리아, 2 => 독일), 확장은 (1 => 이탈리아, 2 => 독일, 3 => 중간)입니다.
lintabá

1
@ 존은 달려있다. MariaDB의 경우 inplace10.3.7부터 열거 형 끝에 새 값을 추가 할 수 있습니다 . mariadb.com/kb/en/library/…
Felipe Philipp

99

귀하의 코드가 저에게 효과적입니다. 내 테스트 사례는 다음과 같습니다.

mysql> CREATE TABLE carmake (country ENUM('Canada', 'United States'));
Query OK, 0 rows affected (0.00 sec)

mysql> SHOW CREATE TABLE carmake;
+---------+-------------------------------------------------------------------------------------------------------------------------+
| Table   | Create Table                                                                                                            |
+---------+-------------------------------------------------------------------------------------------------------------------------+
| carmake | CREATE TABLE `carmake` (
  `country` enum('Canada','United States') default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 |
+---------+-------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

mysql> ALTER TABLE carmake CHANGE country country ENUM('Sweden','Malaysia');
Query OK, 0 rows affected (0.53 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> SHOW CREATE TABLE carmake;
+---------+--------------------------------------------------------------------------------------------------------------------+
| Table   | Create Table                                                                                                       |
+---------+--------------------------------------------------------------------------------------------------------------------+
| carmake | CREATE TABLE `carmake` (
  `country` enum('Sweden','Malaysia') default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 |
+---------+--------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

어떤 오류가 나타 납니까?

다음과 같이 작동합니다.

ALTER TABLE carmake MODIFY COLUMN country ENUM('Sweden','Malaysia');

실제로 열거 형 열이 아닌 국가 테이블을 권장합니다. 다소 크고 어색한 열거 형을 만드는 수백 개의 국가가있을 수 있습니다.

편집 : 이제 오류 메시지가 표시됩니다.

ERROR 1265 (01000): Data truncated for column 'country' at row 1.

국가 열에에 표시되지 않은 값이 있다고 생각합니다 ENUM. 다음 명령의 결과는 무엇입니까?

SELECT DISTINCT country FROM carmake;

다른 편집 : 다음 명령의 출력은 무엇입니까?

SHOW VARIABLES LIKE 'sql_mode';

그것은인가 STRICT_TRANS_TABLES또는 STRICT_ALL_TABLES? 이 상황에서 MySQL이 알려주는 일반적인 경고보다는 오류가 발생할 수 있습니다.

또 다른 편집 : 이제 테이블에 new에없는 값이 있음을 알았습니다 ENUM. 새로운 ENUM정의는 'Sweden'and 만 허용 'Malaysia'합니다. 표는있다 'USA', 'India'그리고 몇몇 다른 사람.

마지막 편집 (MAYBE) :이 작업을 수행하려는 것 같습니다.

ALTER TABLE carmake CHANGE country country ENUM('Italy', 'Germany', 'England', 'USA', 'France', 'South Korea', 'Australia', 'Spain', 'Czech Republic', 'Sweden', 'Malaysia') DEFAULT NULL;

carmake테이블 에 두 개 이상의 열이 있습니다. 그것과 관련이있을 수 있습니까?
Zaid

1
@Zaid는 조심해야합니다. MySQL은 ENUM 열에 가비지를 허용하는 것으로 유명합니다. 예를 들어 부적합한 값을 빈 문자열로 자동 변환합니다. 100 % 불쾌감을주지 않습니까? 빈 줄이 없습니까? 선행 또는 후행 공백이 없습니까? 사례 차이? 악센트 문자?
Asaph

1
@Zaid 업데이트 된 ENUM 정의에없는 값이 테이블에 있다고 생각합니다. 새로운 정의는 스웨덴과 말레이시아 만 허용합니다. 테이블에 미국, 인도, 독일이 있습니다. 새 ENUM에 해당 값을 사용할 수 없습니다. ENUM의 원래 멤버를 유지하면서 스웨덴과 말레이시아를 추가 하려는 경우 ALTER 문에 원래의 모든 ENUM 값과 2 개의 새 값을 모두 다시 나열해야 합니다.
Asaph

2
@Zaid 천만에요. 초기에 제안한 것처럼 ENUM 대신 외래 키가있는 국가 테이블을 사용하는 경우 새 국가에 대한 행을 추가 할 수 있습니다. BTW : 내 제안이 도움이된다면 내 대답을 올바르게 표시하십시오. :)
Asaph

3
-1 실제 해결책이 무엇인지 명확하지 않습니다. 대화가 너무 많고 "이것을 시도하십시오. 대신 시도해보십시오." 초기 응답은 OP의 실제 질문에 대답조차하지 못합니다. 나중에 문제가 무엇인지 깨닫고 나서이 질문 / 답변을 찾는 사람에게 실제로 의미가없는 간단한 코드 샘플로 들어가는 것은 아닙니다. 나중에. 편집 내용의 내용은 일시적이며 더 이상 명확하지 않습니다.
Jim Rubenstein

73

토론 우리가 앞뒤로 꽤 갔다 나는이 아삽과 함께했다 따를 불분명 할 수있다.

나는 미래에 비슷한 상황에 처할 수있는 다른 사람들을 위해 우리의 담론의 결말을 분명히 밝힐 수 있다고 생각했습니다.

ENUM유형 컬럼은 조작하기가 매우 어려운 짐승입니다. ENUM의 기존 국가 세트에 두 국가 (말레이시아 및 스웨덴)를 추가하고 싶었습니다.

MySQL 5.1 (내가 실행중인 것)은 내가 원하는 것 외에도 기존 세트를 재정 의하여 ENUM 만 업데이트 할 수있는 것 같습니다.

이것은 작동하지 않았다 :

ALTER TABLE carmake CHANGE country country ENUM('Sweden','Malaysia') DEFAULT NULL;

그 이유는 MySQL의 문이 또 다른 항목을 포함하여 기존 ENUM를 교체 한 것이 었습니다 'Malaysia''Sweden'단지. MySQL은 때문에 오류를 던졌다 carmake테이블에 이미 한 값이 좋아 'England'하고 'USA'있는 새의 일부가 아닌 ENUM'의 정의.

놀랍게도 다음은 작동하지 않았습니다.

ALTER TABLE carmake CHANGE country country ENUM('Australia','England','USA'...'Sweden','Malaysia') DEFAULT NULL;

ENUM새로운 멤버를 추가하면서 기존 요소의 순서조차도 유지해야 한다는 것이 밝혀졌습니다 . 기존 그래서 만약 ENUM같은 모양의 무언가가 ENUM('England','USA'), 다음 내 새가 ENUM있다으로 정의 할 수 있습니다 ENUM('England','USA','Sweden','Malaysia')하지 ENUM('USA','England','Sweden','Malaysia'). 이 문제는 기존 테이블에 'USA'또는 'England'값 을 사용하는 레코드가있는 경우에만 나타납니다 .

하단 라인 :

ENUM정의 된 멤버 집합이 변경되지 않을 경우 에만 s를 사용 하십시오. 그렇지 않으면 조회 테이블을 업데이트하고 수정하기가 훨씬 쉽습니다.


더 강력한 결론을 내릴 것입니다. "100 % 사망했을 때 ENUM 만 사용하십시오. 테이블이 커지면 해당 값을 변경해야하는 경우 고통이됩니다.
DougW

6
나는 그 결론에 동의하지 않습니다. 나는 ENUM을 전혀 좋아하지 않지만 가능한 ENUM을 추가 할 때 위험을 보지 못한다고 믿어주세요. ENUM의 핵심은 0-> 옵션 1, 1-> 옵션 2 등의 매핑입니다. 여기에 추가해도 문제가 발생하지 않습니다.
JoshStrange 2019

2
@JoshStrange 그다지 위험하지는 않습니다. 예를 들어 주문에 사용될 때 ENUM의 순서가 중요 할 때 큰 불편을 겪을 수 있습니다.
1in9ui5t

1
결론은 MySQL의 레거시 버전에서만 유효하다는 것을 말하는 것이 중요하다고 생각합니다. 새로운 버전에서는 문제가 없기 때문에 이해합니다.
Niccolò

이 답변은 더 이상 관련이 없으며 아래 답변은 수락 된 것으로 표시해야합니다.
ofirski

16

MYSQL 서버 버전 : 5.0.27 나는 이것을 시도하고 당신의 버전에서 나를 위해 잘 작동했습니다.

ALTER TABLE carmake
     MODIFY `country` ENUM('Japan', 'USA', 'England', 'Australia', 'Germany', 'France', 'Italy', 'Spain', 'Czech Republic', 'China', 'South Korea', 'India', 'Sweden', 'Malaysia');

1
왜 이것이 더 많이지지되지 않는지 확실하지 않습니다. 간단하고 저에게 효과적입니다.
조상

1

참고 : 유용한 시뮬레이션 도구-phpMyAdmin with Wampserver 3.0.6-Preview SQL : 'Preview SQL'을 사용하여 ENUM 변경으로 열을 저장하기 전에 생성되는 SQL 코드를 봅니다. SQL 미리보기

위의 ENUM에 'Ford', 'Toyota'를 입력했지만 구문 오류가 발생하는 구문 ENUM (0)이 표시됩니다. 쿼리 오류 1064 #

그런 다음 SQL을 복사하여 붙여넣고 변경하고 SQL을 통해 실행하여 긍정적 인 결과를 얻습니다.

SQL이 변경됨

이것은 내가 자주 사용하는 빠른 수정이며 변경해야하는 기존 ENUM 값에도 사용할 수 있습니다. 이것이 유용 할 것이라고 생각했습니다.


1

다른 방법이 있습니다 ...

"firmas"테이블의 "rtipo"열에 대한 열거 정의에 "others"를 추가합니다.

set @new_enum = 'others';
set @table_name = 'firmas';
set @column_name = 'rtipo';
select column_type into @tmp from information_schema.columns 
  where table_name = @table_name and column_name=@column_name;
set @tmp = insert(@tmp, instr(@tmp,')'), 0, concat(',\'', @new_enum, '\'') );
set @tmp = concat('alter table ', @table_name, ' modify ', @column_name, ' ', @tmp);
prepare stmt from @tmp;
execute stmt;
deallocate prepare stmt;

-8

당신이 믿는다면 가능합니다. 헤헤 이 코드를 사용해보십시오.

public function add_new_enum($new_value)
  {
    $table="product";
    $column="category";
         $row = $this->db->query("SELECT COLUMN_TYPE FROM INFORMATION_SCHEMA.COLUMNS
        WHERE TABLE_NAME = ? AND COLUMN_NAME = ?", array($table, $column))->row_array();

    $old_category = array();
    $new_category="";
    foreach (explode(',', str_replace("'", '', substr($row['COLUMN_TYPE'], 5, (strlen($row['COLUMN_TYPE']) - 6)))) as $val)
    {
        //getting the old category first

        $old_category[$val] = $val;
        $new_category.="'".$old_category[$val]."'".",";
    }

     //after the end of foreach, add the $new_value to $new_category

      $new_category.="'".$new_value."'";

    //Then alter the table column with the new enum

    $this->db->query("ALTER TABLE product CHANGE category category ENUM($new_category)");
  }

새로운 가치를 추가하기 전에

새로운 가치를 더한 후


11
이것이 어떻게 테이블에 새로운 것을 가져 오는지 모르겠습니다. 이 문제는 순수하게 MySQL 관점에서도 나옵니다. 귀하의 답변에는 완전히 관련이없는 임의의 PHP가 포함되어 있으며 설명을 시도하지 않습니다. 쓸모없는 정보 자원
Jonathan
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.