मैं 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)

DISTINCT देश का चयन कार से बाहर करें :

+----------------+
| 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
अधिकांश वैकल्पिक आदेश पूरी तालिका को पूरी तरह से फिर से लिखेंगे। क्या mysql काफी चतुर है जो एनम के साथ ऐसा नहीं करता है?
जॉन

enum एक स्ट्रिंग प्रतिनिधित्व के साथ सिर्फ एक फैंसी पूर्णांक है। अंत में आइटम जोड़ना ठीक है, क्योंकि आप केवल पुराने मूल्यों को जोड़ते हैं। लेकिन आदेशों को बदलने / हटाने से उन संख्याओं को अपरिभाषित कर दिया जाएगा। (उदाहरण। 1 => इटली, 2 => जर्मनी), तब विस्तार होगा (1 => इटली, 2 => जर्मनी, 3 => स्वेन्देन)।
लिंटाबा

1
@ जॉन निर्भर करता है। मारियाबीडी के लिए, एनम के अंत में नए मूल्यों को जोड़ना inplace10.3.7 के बाद से किया जा सकता है : mariadb.com/kb/en/library/…
फेलिप

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)

आप क्या त्रुटि देख रहे हैं?

FWIW यह भी काम करेगा:

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;

ANOTHER EDIT: निम्नलिखित कमांड का आउटपुट क्या है?

SHOW VARIABLES LIKE 'sql_mode';

यह है STRICT_TRANS_TABLESया STRICT_ALL_TABLES? सामान्य चेतावनी के बजाय एक त्रुटि हो सकती है, MySQL आपको इस स्थिति में देगा।

YET ANOTHER EDIT: ठीक है, अब मैं देखता हूं कि आपके पास निश्चित रूप से तालिका में मूल्य हैं जो नए नहीं हैं ENUM। नई ENUMपरिभाषा केवल अनुमति देती है 'Sweden'और 'Malaysia'। टेबल है 'USA', 'India'और कई अन्य।

पिछले संस्करण (मई): मुझे लगता है कि आप ऐसा करने की कोशिश कर रहे हैं:

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

मेरी carmakeतालिका में एक से अधिक कॉलम हैं । क्या इससे कुछ हो सकता है?
ज़ेड

1
@ कहावत के बारे में सावधान रहें। MySQL ENUM कॉलम में कचरा डालने की अनुमति देने के लिए कुख्यात है। उदाहरण के लिए, यह गैर-अनुरूपण मूल्यों को चुपचाप रिक्त तारों में बदल देगा। क्या आप 100% सुनिश्चित हैं कि आपके पास कोई अपमानजनक मूल्य नहीं है? कोई खाली तार नहीं? कोई अग्रणी या अनुगामी व्हाट्सएप नहीं? केस का अंतर? उच्चारण किए गए वर्ण?
आसफ

1
@Zaid मुझे लगता है कि आपके पास अपनी तालिका में ऐसे मान हैं जो आपकी अपडेट की गई ENUM परिभाषा से अनुपस्थित हैं। आपकी नई परिभाषा केवल स्वीडन और मलेशिया की अनुमति देती है। आपकी तालिका में यूएसए, भारत, जर्मनी है ... आपके नए ENUM में उन मानों में से किसी को भी अनुमति नहीं दी जाएगी। यदि आप जो करना चाह रहे हैं , वह ENUM के मूल सदस्यों को संरक्षित करते हुए स्वीडन और मलेशिया को जोड़ने का है, तो आपको अपने ALTER स्टेटमेंट में सभी मूल ENUM मानों और 2 नए लोगों को राहत देने की आवश्यकता होगी ।
आसफ

2
@ आप का स्वागत है। यदि आप ENUM के बजाय किसी विदेशी कुंजी के साथ देशों की तालिका का उपयोग करते हैं जैसा कि मैंने पहले सुझाव दिया था, तो आप नए देशों के लिए बस पंक्तियाँ जोड़ पाएंगे। BTW: अगर आपको मेरे सुझाव मददगार लगे हैं, तो कृपया मेरे उत्तर को सही चिह्नित करें :)
Asaph

3
-1 वास्तविक समाधान क्या है, इस पर स्पष्टता की कमी के लिए। बहुत अधिक बातचीत और "यह कोशिश करो, ओह अच्छी तरह से इसके बजाय प्रयास करें।" प्रारंभिक प्रतिक्रिया भी ओपी के वास्तविक प्रश्न का उत्तर नहीं देती है - यह बाद में तब तक नहीं है जब आपको पता चलता है कि समस्या क्या थी, और फिर आप सरल कोड नमूनों में जाते हैं जो वास्तव में किसी के लिए कोई मतलब नहीं रखते हैं जो इस प्रश्न / उत्तर को ढूंढ रहे हैं बाद में। आपके संपादन का संदर्भ / अस्थायी था, और अब स्पष्ट नहीं है।
जिम रुबेंस्टीन

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तब ही एस का उपयोग करें जब आप अपने सदस्यों के सेट को एक बार परिभाषित करने के लिए बदलने की उम्मीद नहीं करते हैं। अन्यथा, लुकअप टेबल अद्यतन और संशोधित करने के लिए बहुत आसान है।


मैं एक मजबूत निचली रेखा का उपक्रम करूँगा ... "केवल ENUM का उपयोग करें जब आप 100% निश्चित सकारात्मक हो कि मान कभी नहीं बदलेंगे"। यदि कोई तालिका बड़ी हो जाती है, तो यह दर्द होगा यदि आपको कभी उन मूल्यों को बदलना होगा।
डग डब्लू

6
मुझे यकीन नहीं है कि मैं उस नीचे की रेखा से सहमत हूं। मुझे विश्वास है कि मुझे ENUM बिल्कुल पसंद नहीं है, लेकिन मुझे संभव ENUM के लिए खतरे में नहीं दिख रहा है। ENUM है, यह कोर पर है, 0 की एक मैपिंग -> विकल्प 1, 1-> विकल्प 2, आदि को जोड़ने से कोई समस्या नहीं होनी चाहिए।
२०:०२ पर जोश स्ट्रेंज

2
@JoshStrange यह इतना खतरा नहीं है, यह तब भारी असुविधा हो सकती है जब आपका ENUM का क्रम महत्वपूर्ण हो (उदाहरण के लिए, जब ऑर्डर करने के लिए उपयोग किया जाता है)।
1in9ui5t

1
मुझे लगता है कि नीचे की पंक्ति में यह कहना भी महत्वपूर्ण है कि यह केवल MySQL के विरासत संस्करणों के साथ मान्य है क्योंकि जो मैं समझता हूं, नए लोगों के साथ कोई समस्या नहीं है।
निकोलो

यह उत्तर अब प्रासंगिक नहीं है, नीचे दिए गए को स्वीकार किया जाना चाहिए।
आइरस्की

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

FYI करें: Wampserver 3.0.6 के साथ एक उपयोगी सिमुलेशन टूल - phpMyAdmin - पूर्वावलोकन SQL: मैं ENUM को बदलने के साथ कॉलम को सहेजने से पहले उत्पन्न होने वाले SQL कोड को देखने के लिए 'पूर्वावलोकन SQL' का उपयोग करता हूं। SQL का पूर्वावलोकन करें

ऊपर आप देखें कि मैंने ENUM में 'Ford', 'Toyota' में प्रवेश किया है, लेकिन मुझे वाक्यविन्यास ENUM (0) मिल रहा है, जो वाक्य रचना त्रुटि क्वेरी त्रुटि 1064 # उत्पन्न कर रहा है

मैं तब कॉपी और पेस्ट करता हूं और एसक्यूएल को बदल देता हूं और इसे सकारात्मक परिणाम के साथ एसक्यूएल के माध्यम से चलाता हूं।

एसक्यूएल बदल गया

यह एक क्विकफ़िक्स है जिसे मैं अक्सर उपयोग करता हूं और मौजूदा ENUM मूल्यों पर भी उपयोग किया जा सकता है जिन्हें परिवर्तित करने की आवश्यकता है। सोचा यह उपयोगी हो सकता है।


1

यहाँ एक और तरीका है ...

यह तालिका "फर्मस" के कॉलम "rtipo" की enum परिभाषा में "अन्य" जोड़ता है।

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 को शामिल करता है जो पूरी तरह से अप्रासंगिक है और आप इसमें से किसी को भी समझाने का कोई प्रयास नहीं करते हैं। जानकारी का बेकार संसाधन
जोनाथन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.