Pytanie Jak utworzyć typ ENUM w SQLite?


Muszę przekonwertować tabelę z MySQL na SQLite, ale nie mogę wymyślić, jak przekonwertować pole wyliczeniowe, ponieważ nie mogę znaleźć ENUM wpisz SQLite.

Wspomniane pole to pType w poniższej tabeli:

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

Potrzebuję pola zawierającego tylko trzy wartości do wyboru przez użytkownika i chciałbym to wymusić w DB, a nie tylko w mojej aplikacji.


76
2018-03-14 13:34


pochodzenie




Odpowiedzi:


W SQLite nie ma typu wyliczeniowego, a jedynie:

  • ZERO
  • LICZBA CAŁKOWITA
  • REAL
  • TEKST
  • KROPELKA

Źródło: http://www.sqlite.org/datatype3.html

Obawiam się, że w twoim przypadku wymagany będzie mały, niestandardowy stół do enum.


54
2018-03-14 15:52



Właściwie "niestandardowy tabelę enum" to znacznie czystszy projekt, który wykorzystuje rzeczywiste wyliczenia - a_horse_with_no_name
Dlaczego nie stosować ograniczenia CHECK (), aby zezwalać tylko na trzy możliwe łańcuchy? - mateusza
> zezwól tylko na trzy możliwe ciągi: Z powodu przechowywania ciągu? - Caleb Paul
@Wideshanks Nie sądzę CHECK() istniało w momencie, gdy pisałem tę odpowiedź. O ile nie jest ciąg naprawdę krótkie, jestem całkowicie przeciwny. Maksymalnie 1 lub 2 znaki. - MPelletier
@HammanSamuel To nie jest nowy, to jest rozwiązane w znaczeniu TEXT. Na stronie źródłowej podałem, patrz punkt 2.1 na temat określania powinowactwa kolumny. - MPelletier


Sposób SQLite

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

59
2018-06-19 23:29





Jeśli przyjdziecie do tego w przyszłości, aby rozwinąć odpowiedź MPelletiera, możecie stworzyć tabele jako:

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

Tak wykonane, wartości wyliczeniowe są dostępne bezpośrednio w tabeli Cennik, ponieważ wykorzystywałyby ENUM: nie musisz dołączać do tabeli PriceType, aby uzyskać wartości typu, musisz go użyć tylko, jeśli chcesz określić sekwencja ENUM.

Ograniczenia klucza obcego zostały wprowadzone w SQLite w wersji 3.6.19.


49
2018-05-30 07:30



INSERT INTO PriceType(Type, Seq) VALUES ('M',1), ('R',2), ('H',3); Powinien dostać błąd składni. "Pierwsza forma (ze słowem kluczowym" VALUES ") tworzy pojedynczy nowy wiersz w istniejącej tabeli.": sqlite.org/lang_insert.html. Złam to, aby tego uniknąć: 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
Była odpowiedź, która miała być komentarzem, ale teraz jej nie ma. Zasadniczo od SQLite 3.7.11 można wprowadzić kilka pozycji za pomocą INSERT. Poprawiona składnia nadal działa. - MPelletier
Nie zapomnij PRAGMA foreign_keys = ON; dla każdej sesji - ponieważ fkeys są domyślnie wyłączone w sqlite3 - smathy
Jeśli chcesz uniknąć zapomnienia PRAGMA foreign_keys = ON; możesz to ustawić w swoim pliku .sqliterc w swoim katalogu domowym. - Eradicatore
Ponadto możesz chcieć użyć UNIQUE ograniczenie na Seq. Coś takiego CREATE TABLE PriceType( Type Char(1) PRIMARY KEY NOT NULL, Seq INTEGER UNIQUE); - Eradicatore