SQLite'da ENUM türü nasıl oluşturulur?


105

Bir tabloyu MySQL'den SQLite'a dönüştürmem gerekiyor, ancak SQLite'de ENUMtür bulamadığım için bir enum alanını nasıl dönüştüreceğimi çözemiyorum.

Yukarıda belirtilen alan pTypeaşağıdaki tablodadır:

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

Kullanıcının seçmesi için yalnızca üç değer içeren bir alana ihtiyacım var ve bunu yalnızca uygulamamda değil DB'de de uygulamak istiyorum.

Yanıtlar:


81

SQLite'de enum türü yoktur, yalnızca aşağıdakiler vardır:

  • BOŞ
  • TAM
  • GERÇEK
  • METİN
  • BLOB

Kaynak: http://www.sqlite.org/datatype3.html

Korkarım sizin durumunuzda küçük, özel bir enum tablosu gerekecek.


26
Aslında "özel bir enum tablosu", gerçek numaralandırmaları kullanan çok daha temiz bir tasarım
a_horse_with_no_name

19
Neden yalnızca üç olası dizeye izin vermek için CHECK () kısıtını kullanmıyorsunuz?
mateusza

1
@Wideshanks Ben CHECK()bu cevabı yazdığım zaman var olduğunu sanmıyorum . İp gerçekten kısa değilse, tamamen karşıyım. Maksimum 1 veya 2 karakter.
MPelletier

VARCHARSQLite sürümümde kullanabilirim , bu yeni bir tür eki mi?
Hamman Samuel

3
@HammanSamuel Yeni değil, anlam olarak çözüldü TEXT. Verdiğim kaynak sayfada, Sütun Yakınlığının Belirlenmesi hakkındaki 2.1 numaralı maddeye bakın.
MPelletier

106

SQLite yolu, bir CHECK kısıtlaması kullanmaktır .

Bazı örnekler:

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'
)

Bu sınırlar pTypesadece değerlere sütun M, Rve Htıpkı enum("M", "R", "H")diğer bazı SQL motorlarında yapardı.


2
Welp, aslında bu uygulama tam olarak taklit etmez enumçünkü değerlerin tamsayı indeksine göre sıralamayı imkansız kılar (gerçek enumalanla mümkündür ). Sadece herkes, bunu aklınızda bulundurun.
Boris D. Teoharov

53

MPelletier'in cevabını genişletmek için aşağıdaki gibi tablolar oluşturabilirsiniz:

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

Artık numaralandırma değerleri, bir ENUM kullanacakları için doğrudan Fiyat tablosunda mevcuttur: Tür değerlerini almak için PriceType tablosuna katılmanız gerekmez, yalnızca sırasını belirlemek istiyorsanız kullanmanız gerekir. ENUM'lar.

Yabancı anahtar kısıtlamaları SQLite 3.6.19 sürümünde tanıtıldı.


3
INSERT INTO PriceType(Type, Seq) VALUES ('M',1), ('R',2), ('H',3);Size bir sözdizimi hatası almalı. "İlk form (" DEĞERLER "anahtar kelimesi ile), mevcut bir tabloda tek bir yeni satır oluşturur." : 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);
Ayrıl şunlardan

9
PRAGMA foreign_keys = ON;Her oturum için unutmayın - çünkü sqlite3'te fkey'ler varsayılan olarak devre dışı bırakıldı
smathy

3
Unutmaktan kaçınmak PRAGMA foreign_keys = ON;istiyorsanız, bunu ana dizininizdeki .sqliterc dosyanıza kurabilirsiniz.
Eradicatore

1
Ayrıca, UNIQUESeq kısıtlamasını kullanmak isteyebilirsiniz . Bunun gibi bir şeyCREATE TABLE PriceType( Type Char(1) PRIMARY KEY NOT NULL, Seq INTEGER UNIQUE);
Eradicatore

1
Yalnızca varsayılan satır kimliği sütununu kullanmak yerine neden ayrı bir 'Seq' sütunu oluşturursunuz ?
Parthian Shot
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.