MySQL'deki ENUM türü sütunuma nasıl daha fazla üye ekleyebilirim?


157

MySQL başvuru kılavuzu, bunun nasıl yapılacağı konusunda kesin bir örnek sağlamaz.

Daha fazla ülke eklemem gereken ENUM türü bir ülke adı sütunum var. Bunu başarmak için doğru MySQL sözdizimi nedir?

İşte benim girişimim:

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

Aldığım hata: ERROR 1265 (01000): Data truncated for column 'country' at row 1.

countrySütun yukarıda açıklamada ENUM tipi sütundur.

TABLO ÇIKIŞINI GÖSTER :

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)

ARAÇ ÇIKIŞINDAN DISTINCT ülkesini seçin :

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

Yanıtlar:


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

7
Çoğu ALTER TABLE komutu tüm tabloyu tamamen yeniden yazar. MySQL enum ile bunu yapmak için yeterince zeki mi?
John

enum, bir dize temsiliyle sadece süslü bir tamsayıdır. Sonuna öğe eklemek iyidir, çünkü eski değerleri anlamlandırırsınız. ancak sıraların değiştirilmesi / numaraların kaldırılması bu sayıların tanımsız olmasını sağlar. (ör. 1 => İtalya, 2 => almanya), daha sonra genişletme (1 => İtalya, 2 => almanya, 3 => sweenden) olacaktır.
lintabá

1
@John bağlıdır. MariaDB için, inplacesayımın sonuna yeni değerler eklemek 10.3.7'den beri yapılabilir: mariadb.com/kb/en/library/…
Felipe Philipp

99

Kodun benim için çalışıyor. İşte benim test durumum:

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)

Hangi hatayı görüyorsun?

FWIW bu da işe yarar:

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

Aslında enum sütun yerine bir ülke tablo öneriyoruz. Oldukça büyük ve garip bir numaralandırma yapacak yüzlerce ülkeye sahip olabilirsiniz.

DÜZENLEME: Artık hata iletinizi görebildiğime göre:

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

Ülke sütununuzda görünmeyen bazı değerleriniz olduğundan şüpheleniyorum ENUM. Aşağıdaki komutun çıktısı nedir?

SELECT DISTINCT country FROM carmake;

BAŞKA BİR DÜZENLEME: Aşağıdaki komutun çıktısı nedir?

SHOW VARIABLES LIKE 'sql_mode';

Öyle mi STRICT_TRANS_TABLESyoksa STRICT_ALL_TABLES? Bu, MySQL'in size bu durumda vereceği olağan uyarı yerine hataya neden olabilir.

BAŞKA BİR DÜZENLEME: Tamam, şimdi tabloda kesinlikle yeni olmayan değerlere sahip olduğunuzu görüyorum ENUM. Yeni ENUMtanım yalnızca 'Sweden've öğelerine izin verir 'Malaysia'. Masa vardır 'USA', 'India've birkaç diğerleri.

SON DÜZENLEME (MAYBE): Sanırım bunu yapmaya çalışıyorsun:

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

Masamda birden fazla sütun var carmake. Bunun onunla bir ilgisi olabilir mi?
Zaid

1
@Zaid bunu söylerken dikkatli ol. MySQL, ENUM sütunlarına çöp girmesine izin veren ünlüdür. Örneğin, uygun olmayan değerleri sessiz bir şekilde boş dizelere dönüştürür. Sorunlu değerleriniz olmadığından% 100 emin misiniz? Boş dize yok mu? Öncü veya arka boşluk yok mu? Olgu farklılıkları? Aksanlı karakterler mi?
Asaph

1
@Zaid Bence tablonuzda güncellenmiş ENUM tanımınızda bulunmayan değerler var. Yeni tanımınız yalnızca İsveç ve Malezya'ya izin veriyor. Tablonuzda ABD, Hindistan, Almanya var ... Yeni ENUM'unuzda bu değerlerin hiçbirine izin verilmeyecek. Ne yapmaya çalışıyorsun ise eklemek ENUM özgün üyelerini koruyarak İsveç ve Malezya, sen relist gerekir tüm senin alter açıklamada orijinal ENUM değerleri artı 2 yenilerini.
Asaph

2
@Zaid Bir şey değil. Daha önce önerdiğim gibi ENUM yerine yabancı anahtarlı bir ülke tablosu kullanırsanız, yeni ülkeler için yalnızca satırlar ekleyebilirsiniz. BTW: Önerilerimi yararlı bulduysanız, lütfen cevabımı doğru işaretleyin :)
Asaph

3
-1 Burada asıl çözümün ne olduğu konusunda netlik eksikliği. Çok fazla konuşma var ve bir sürü "bunu dene, ah bunun yerine dene." İlk yanıt OP'nin asıl sorusunu bile yanıtlamıyor - daha sonra sorunun ne olduğunu anlamanız değil ve daha sonra bu soruyu / cevabı bulan birine gerçekten bir şey ifade etmeyen basit kod örneklerine giriyorsunuz. daha sonra. Düzenlemelerinizin içeriği geçiciydi / geçiciydi ve artık belli değil.
Jim Rubenstein

73

Tartışma biz ileri geri biraz gitti gibi Asaf'ın ile yaptığı takip etmek net olmayabilir.

Gelecekte benzer durumlarla karşılaşabilecekleri için söylemimizin sonucunu netleştirebileceğimi düşündüm:

ENUM-tip sütunları manipüle etmek çok zor hayvanlardır. ENUM'umdaki mevcut ülkelere iki ülke (Malezya ve İsveç) eklemek istedim.

Görünüşe göre MySQL 5.1 (çalıştırdığım şey) ENUM'u sadece istediğim şeye ek olarak mevcut seti yeniden tanımlayarak güncelleyebilir:

Bu işe yaramadı:

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

Sebebi MySQL deyimi başka girdileri içeren mevcut enum yerine olmasıydı 'Malaysia've 'Sweden'sadece. carmakeTabloda zaten gibi 'England've 'USA'yeni ENUMtanımın bir parçası olmayan değerler olduğu için MySQL hata verdi .

Şaşırtıcı bir şekilde, aşağıdakiler de işe yaramadı:

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

ENUMYeni üyeler eklerken mevcut elemanların sırasının bile korunması gerektiği ortaya çıkıyor. Eğer ENUMmevcutum gibi bir şey gibi görünüyorsa ENUM('England','USA'), o zaman benim yeni ENUMolarak tanımlanmalı ENUM('England','USA','Sweden','Malaysia')ve tanımlanmamalıdır ENUM('USA','England','Sweden','Malaysia'). Bu sorun, yalnızca varolan tabloda 'USA'veya 'England'değerleri kullanan kayıtlar olduğunda ortaya çıkar .

SONUÇ OLARAK:

Yalnızca ENUMüye kümenizin tanımlandıktan sonra değişmesini beklemiyorsanız kullanın. Aksi takdirde, arama tablolarının güncellenmesi ve değiştirilmesi çok daha kolaydır.


Daha güçlü bir alt çizgiye girerim ... "ENUM'ları yalnızca değerlerin asla değişmeyeceğinden emin olduğunuz% 100 ölü olduğunuzda kullanın". Bir tablo büyürse, bu değerleri değiştirmek zorunda kalırsanız ağrı olur.
DougW

6
Bu alt çizgiye katıldığımdan emin değilim. Güven bana ENUM'ları hiç sevmiyorum ama olası ENUM'a EKLEME tehlikesini görmüyorum. ENUM, özünde, 0 -> Seçenek 1, 1-> Seçenek 2 vb. Eşlemesidir. Buna eklemek bir soruna neden olmamalıdır.
JoshStrange

2
@JoshStrange Bu bir tehlike değil, ENUM'unuzun sırası önemli olduğunda (örneğin sipariş için kullanıldığında) büyük bir rahatsızlık olabilir.
1in9ui5t

1
En alt satırda bunun sadece MySQL'in eski sürümleri için geçerli olduğunu söylemek önemli olduğunu düşünüyorum, çünkü anladığım kadarıyla yeni olanlarla ilgili bir sorun yok.
Niccolò

Bu cevap artık geçerli değil, aşağıdaki yanıt kabul edilmiş olarak işaretlenmelidir.
ofirski

17

MYSQL sunucu sürümünde: 5.0.27 Bunu denedim ve benim için iyi çalıştı versiyonunuzu kontrol edin

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

1
Bunun neden daha fazla seçilmediğinden emin değilim. Çok basit ve benim için çalışıyor.
ataların

1

FYI: Yararlı bir simülasyon aracı - Wampserver 3.0.6 ile phpMyAdmin - SQL Önizleme: ENUM değişikliği ile sütunu kaydetmeden önce oluşturulacak SQL kodunu görmek için 'Önizleme SQL' kullanıyorum. Önizleme SQL

Yukarıda ENUM'a 'Ford', 'Toyota' yazdığımı görüyorsunuz fakat sözdizimi hatası üreten ENUM (0) sözdizimi alıyorum Sorgu hatası 1064 #

Sonra kopyalayıp yapıştırın ve SQL değiştirmek ve olumlu bir sonuç ile SQL üzerinden çalıştırın.

SQL değişti

Bu, sık kullandığım bir düzeltmedir ve değiştirilmesi gereken mevcut ENUM değerlerinde de kullanılabilir. Bunun yararlı olabileceğini düşündüm.


1

İşte başka bir yol ...

"Firmas" tablosunun "rtipo" sütunununum tanımına "diğerleri" ekler.

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

Eğer inanırsan mümkün. Hehe. bu kodu deneyin.

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

Yeni değer eklemeden önce

Yeni değer ekledikten sonra


11
Bunun masaya nasıl yeni bir şey getirdiğini anlamıyorum. Soru tamamen MySQL açısından. Cevabınız tamamen ilgisiz rastgele PHP içeriyor ve hiçbirini açıklamaya çalışmıyorsunuz. Yararsız bilgi kaynağı
Jonathan
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.