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.