SQLiteテーブルの制約-複数の列で一意


179

SQLiteのWebサイトでこれに構文「チャート」を見つけることができますが、例がなく、コードがクラッシュしています。1つの列に一意の制約がある他のテーブルがありますが、2つの列のテーブルに制約を追加します。これは、「構文エラー」というメッセージを含むSQLiteExceptionを引き起こしているものです。

CREATE TABLE name (column defs) 
UNIQUE (col_name1, col_name2) ON CONFLICT REPLACE

私はこれを以下に基づいて行っています:

テーブル制約

明確にするために、私が提供したリンクのドキュメントにはCONTSTRAINT name、制約の定義の前に来る必要があると書かれています。

しかし、解決策につながる可能性があるのは、括弧で囲まれた列定義に続くものがデバッガが不平を言うところです。

入れたら

...last_column_name last_col_datatype) CONSTRAINT ...

エラーは「CONSTRAINT」の近くにあります:構文エラー

入れたら

...last_column_name last_col_datatype) UNIQUE ...

エラーは「UNIQUE」に近い:構文エラー


1
それが始まる前にUNIQUEは、カンマが含まれていません...
マジッドバシルを

回答:


345

UNIQUE宣言を列定義セクション内に配置します。作業例:

CREATE TABLE a (
    i INT,
    j INT,
    UNIQUE(i, j) ON CONFLICT REPLACE
);

6
いい答え+1。この作成構文では、SQLiteDatabase.CONFLICT_REPLACEフラグを指定したinsertWithOnConflictではなく、通常の挿入メソッドを使用できますか?
Oleg Belousov 2014年

3
ON CONFLICT IGNORE2つを超える列で(まだ置換を試していません)を使用していますが、一意の制約を順守しているようには見えません。重複を単純に追加するだけです。
マイケル

5
どうやら私はNULL列を持っているので、それはウィンドウのユニークなチェックを実行するだけです
Michael

ON CONFLICT REPLACE新しい行を挿入できるようにするために、既存の行を削除して、それを使用することが望ましくない場合があることに注意してください。通常、制約違反を中止またはロールバックします。SQLite ON CONFLICT句
karmakaze

9

まあ、あなたの構文はあなたが含めたリンクと一致しません。

 CREATE TABLE name (column defs) 
    CONSTRAINT constraint_name    -- This is new
    UNIQUE (col_name1, col_name2) ON CONFLICT REPLACE

私は最初それをしました...うまくいきませんでした。念のためもう一度試してみましたが、それでもうまくいきませんでした
Rich

1

挿入時に異なる結果が得られるように、テーブルの定義方法に注意してください。以下を検討してください



CREATE TABLE IF NOT EXISTS t1 (id INTEGER PRIMARY KEY, a TEXT UNIQUE, b TEXT);
INSERT INTO t1 (a, b) VALUES
    ('Alice', 'Some title'),
    ('Bob', 'Palindromic guy'),
    ('Charles', 'chucky cheese'),
    ('Alice', 'Some other title') 
    ON CONFLICT(a) DO UPDATE SET b=excluded.b;
CREATE TABLE IF NOT EXISTS t2 (id INTEGER PRIMARY KEY, a TEXT UNIQUE, b TEXT, UNIQUE(a) ON CONFLICT REPLACE);
INSERT INTO t2 (a, b) VALUES
    ('Alice', 'Some title'),
    ('Bob', 'Palindromic guy'),
    ('Charles', 'chucky cheese'),
    ('Alice', 'Some other title');

$ sqlite3 test.sqlite
SQLite version 3.28.0 2019-04-16 19:49:53
Enter ".help" for usage hints.
sqlite> CREATE TABLE IF NOT EXISTS t1 (id INTEGER PRIMARY KEY, a TEXT UNIQUE, b TEXT);
sqlite> INSERT INTO t1 (a, b) VALUES
   ...>     ('Alice', 'Some title'),
   ...>     ('Bob', 'Palindromic guy'),
   ...>     ('Charles', 'chucky cheese'),
   ...>     ('Alice', 'Some other title') 
   ...>     ON CONFLICT(a) DO UPDATE SET b=excluded.b;
sqlite> CREATE TABLE IF NOT EXISTS t2 (id INTEGER PRIMARY KEY, a TEXT UNIQUE, b TEXT, UNIQUE(a) ON CONFLICT REPLACE);
sqlite> INSERT INTO t2 (a, b) VALUES
   ...>     ('Alice', 'Some title'),
   ...>     ('Bob', 'Palindromic guy'),
   ...>     ('Charles', 'chucky cheese'),
   ...>     ('Alice', 'Some other title');
sqlite> .mode col
sqlite> .headers on
sqlite> select * from t1;
id          a           b               
----------  ----------  ----------------
1           Alice       Some other title
2           Bob         Palindromic guy 
3           Charles     chucky cheese   
sqlite> select * from t2;
id          a           b              
----------  ----------  ---------------
2           Bob         Palindromic guy
3           Charles     chucky cheese  
4           Alice       Some other titl
sqlite> 

挿入/更新の効果は同じidですが、テーブル定義のタイプに基づいて変更されます(「アリス」が現在持っている2番目のテーブルを参照してくださいid = 4。最初のテーブルは、私が期待するよりも多くのことを実行しています。PRIMARYKEYは同じにしてください) )。この影響に注意してください。


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.