SQLiteでENUM型を作成する方法は?


104

テーブルをMySQLからSQLiteに変換する必要がありますが、SQLiteでENUM型を見つけることができないため、列挙フィールドを変換する方法がわかりません。

前述のフィールドは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

ユーザーが選択できる値が3つしかないフィールドが必要です。これを、アプリケーションだけでなく、DBにも適用したいと考えています。

回答:


81

SQLiteには列挙型はありません。次のものだけです。

  • ヌル
  • 整数
  • リアル
  • テキスト
  • BLOB

出典:http : //www.sqlite.org/datatype3.html

小さなカスタムenumテーブルが必要になる場合があります。


26
実際、「カスタムenumテーブル」は、実際のenumを使用したより
すっきりした

19
CHECK()制約を使用して、可能な3つの文字列のみを許可しないのはなぜですか?
mateusza 2013年

1
@Wideshanks私がCHECK()その回答を書いた当時は存在していなかったと思います。文字列が本当に短い場合を除いて、私はそれに完全に反対しています。最大1文字または2文字。
MPelletier 2014年

VARCHARSQLiteバージョンで使用できますが、それは新しい型の追加ですか?
Hamman Samuel

3
@HammanSamuel新しいものではなく、意味として解決されTEXTます。私が提供したソースページで、列の親和性の決定に関するポイント2.1を参照してください。
MPelletier 2015年

105

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

これにより、他のSQLエンジンと同様に、pType列が値、、およびに制限されます。MRHenum("M", "R", "H")


2
実はenum、実際のenumフィールドでは可能ですが、値の整数インデックスでソートすることができないため、実際にはこの実装は完全にエミュレートしません。ただ、皆さん、それを覚えておいてください。
ボリスD.テハロフ

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を使用する場合と同様に、列挙値はPriceテーブルで直接利用できます。Type値を取得するためにPriceTypeテーブルに結合する必要はありません。シーケンスを決定する場合にのみ使用する必要があります。 ENUM。

外部キー制約は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ではデフォルトでfkeyが無効になっているため
smathy

3
忘れないようにする場合PRAGMA foreign_keys = ON;は、ホームディレクトリの.sqlitercファイルに設定できます。
Eradicatore

1
また、UNIQUESeq の制約を使用することもできます。このような何かCREATE TABLE PriceType( Type Char(1) PRIMARY KEY NOT NULL, Seq INTEGER UNIQUE);
Eradicatore

1
デフォルトのROWID列を使用するのではなく、別の「Seq」列を作成するのはなぜですか?
パルティアンショット
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.