SQLite में ENUM टाइप कैसे बनाएं?


105

मुझे MySQL से SQLite में एक तालिका बदलने की आवश्यकता है, लेकिन मैं यह पता नहीं लगा सकता कि एनुम फ़ील्ड को कैसे परिवर्तित किया जाए, क्योंकि मैं ENUMSQLite में टाइप नहीं कर सकता ।

उपर्युक्त फ़ील्ड pTypeनिम्न तालिका में है:

CREATE TABLE `prices` (
    `id` INT(11) NOT NULL AUTO_INCREMENT,
    `pName` VARCHAR(100) NOT NULL DEFAULT '',
    `pType` ENUM('M','R','H') NOT NULL DEFAULT 'M',
    `pField` VARCHAR(50) NULL DEFAULT NULL,
    `pFieldExt` VARCHAR(50) NULL DEFAULT NULL,
    `cmp_id` INT(11) NOT NULL DEFAULT '0',
    PRIMARY KEY (`id`)
)
ENGINE=MyISAM
ROW_FORMAT=DEFAULT

मुझे उपयोगकर्ता को चुनने के लिए केवल तीन मानों के साथ एक फ़ील्ड की आवश्यकता है, और मैं इसे डीबी में लागू करना चाहूंगा, न कि केवल मेरे आवेदन में।

जवाबों:


81

SQLite में कोई एनम प्रकार नहीं है, केवल निम्नलिखित:

  • शून्य
  • पूर्णांक
  • असली
  • पाठ
  • ब्लॉब

स्रोत: http://www.sqlite.org/datatype3.html

मुझे एक छोटा सा डर है, आपके मामले में कस्टम एनम टेबल की आवश्यकता होगी।


26
वास्तव में "एक कस्टम एनम टेबल" एक बहुत क्लीनर डिज़ाइन है जो वास्तविक
एनमों

19
केवल तीन संभावित तारों को अनुमति देने के लिए CHECK () बाधा का उपयोग क्यों नहीं किया जाता है?
माटूसज़ा

1
CHECK()उस समय मैंने जो उत्तर लिखा था, उस पर मुझे नहीं लगता । जब तक स्ट्रिंग वास्तव में छोटा नहीं होता, मैं पूरी तरह से इसके खिलाफ हूं। अधिकतम 1 या 2 वर्ण।
MPelletier

मैं VARCHARअपने SQLite संस्करण में उपयोग कर सकता हूं , क्या यह एक नया प्रकार है?
हैमैन सैमुअल

3
@ HammanSamuel यह नया नहीं है, यह अर्थ के रूप में हल हो गया है TEXT। मेरे द्वारा दिए गए स्रोत पृष्ठ पर, स्तंभ आत्मीयता के निर्धारण पर बिंदु 2.1 देखें।
MPelletier

106

SQLite तरीका एक CHECK बाधा का उपयोग करना है ।

कुछ उदाहरण:

CREATE TABLE prices (
 id         INTEGER                                PRIMARY KEY,
 pName      TEXT CHECK( LENGTH(pName) <= 100 )     NOT NULL DEFAULT '',
 pType      TEXT CHECK( pType IN ('M','R','H') )   NOT NULL DEFAULT 'M',
 pField     TEXT CHECK( LENGTH(pField) <= 50 )     NULL DEFAULT NULL,
 pFieldExt  TEXT CHECK( LENGTH(pFieldExt) <= 50 )  NULL DEFAULT NULL,
 cmp_id     INTEGER                                NOT NULL DEFAULT '0'
)

यह सीमित कर देगा pTypeसिर्फ मूल्यों के स्तंभ M, Rऔर H, जैसे enum("M", "R", "H")कुछ अन्य एसक्यूएल इंजन में करना होगा।


2
वेल्ड, वास्तव में यह कार्यान्वयन पूरी तरह से अनुकरण नहीं करता है enumक्योंकि यह मूल्यों के पूर्णांक सूचकांक (जो एक वास्तविक enumक्षेत्र के साथ संभव है ) द्वारा सॉर्ट करना असंभव बनाता है । बस, हर कोई, इसे ध्यान में रखें।
बोरिस डी। तेहरोव 15

53

MPelletier के उत्तर पर विस्तार करने के लिए, आप तालिकाएँ इस तरह बना सकते हैं:

CREATE TABLE Price (
  PriceId INTEGER       PRIMARY KEY AUTOINCREMENT NOT NULL,
  Name    VARCHAR(100)  NOT NULL,
  Type    CHAR(1)       NOT NULL DEFAULT ('M') REFERENCES PriceType(Type)
);

CREATE TABLE PriceType (
  Type    CHAR(1)       PRIMARY KEY NOT NULL,
  Seq     INTEGER
);
INSERT INTO PriceType(Type, Seq) VALUES ('M',1);
INSERT INTO PriceType(Type, Seq) VALUES ('R',2);
INSERT INTO PriceType(Type, Seq) VALUES ('H',3);

अब गणना मूल्य सीधे मूल्य तालिका में उपलब्ध हैं क्योंकि वे एक ENUM का उपयोग कर रहे हैं: आपको टाइप मान प्राप्त करने के लिए PriceType तालिका में शामिल होने की आवश्यकता नहीं है, आपको केवल इसका उपयोग करना होगा यदि आप अनुक्रम का निर्धारण करना चाहते हैं ENUMs।

विदेशी प्रमुख बाधाओं को SQLite संस्करण 3.6.19 में पेश किया गया था।


3
INSERT INTO PriceType(Type, Seq) VALUES ('M',1), ('R',2), ('H',3);आपको सिंटेक्स त्रुटि मिलनी चाहिए। "पहला फ़ॉर्म (" VALUES "कीवर्ड के साथ) मौजूदा तालिका में एक नई पंक्ति बनाता है।" : sqlite.org/lang_insert.html । इससे बचें कि इससे बचें:INSERT INTO PriceType(Type, Seq) VALUES ('M',1); INSERT INTO PriceType(Type, Seq) VALUES ('R',2); INSERT INTO PriceType(Type, Seq) VALUES ('H',3);
ahcox

9
PRAGMA foreign_keys = ON;हर सत्र के लिए मत भूलना - क्योंकि sqlite3 में
fkeys

3
यदि आप भूलने से बचना PRAGMA foreign_keys = ON;चाहते हैं तो आप अपने .sqliterc फ़ाइल को अपने होम डायरेक्टरी में सेट कर सकते हैं।
एराडिसटोर

1
इसके अलावा, आप UNIQUESeq पर बाधा का उपयोग करना चाह सकते हैं । कुछ इस तरह सेCREATE TABLE PriceType( Type Char(1) PRIMARY KEY NOT NULL, Seq INTEGER UNIQUE);
Eradicatore

1
आप केवल डिफ़ॉल्ट पंक्तिबद्ध कॉलम का उपयोग करने के बजाय एक अलग 'Seq' कॉलम क्यों बनाएंगे ?
पार्थियन ने
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.