SQLite tablo kısıtı - birden çok sütunda benzersiz


179

Ben SQLite web sitesinde sözdizimi "grafikler" bulabilirsiniz, ancak hiçbir örnek ve kodum çöküyor. Tek bir sütunda benzersiz kısıtlamaları olan diğer tabloları var, ancak iki sütundaki tabloya bir kısıtlama eklemek istiyorum. Ben "sözdizimi hatası" mesajı ile bir SQLiteException neden olan budur.

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

Bunu aşağıdakilere dayanarak yapıyorum:

Tablo-kısıtlaması

Açık olmak gerekirse, sağladığım bağlantıdaki belgeler bunun CONTSTRAINT namekısıt tanımımdan önce gelmesi gerektiğini söylüyor .

Ancak çözüme yol açabilecek bir şey, parantez içindeki sütun tanımlarımdan sonra gelen her şey hata ayıklayıcının şikayet ettiği şeydir.

Eğer koyarsam

...last_column_name last_col_datatype) CONSTRAINT ...

hata "CONSTRAINT" yakınında: sözdizimi hatası

Eğer koyarsam

...last_column_name last_col_datatype) UNIQUE ...

hata "UNIQUE" yakınında: sözdizimi hatası


1
EŞSİZ başlamadan önce virgül eksik ..
Majid Bashir

Yanıtlar:


345

UNIQUE bildirimini sütun tanımı bölümüne yerleştirin; çalışma örneği:

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

6
Güzel cevap +1. Bu oluşturma sözdizimi SQLiteDatabase.CONFLICT_REPLACE bayrağıyla insertWithOnConflict'i değil, normal ekleme yöntemini kullanmama izin veriyor mu?
Oleg Belousov

3
ON CONFLICT IGNORE2'den fazla sütunla (henüz değiştirmeyi denemedim) kullanıyorum , ancak benzersiz kısıtlamayı onurlandırdığını görmüyorum, sadece neşeyle kopyaları ekliyor.
Michael

5
Görünüşe göre NULL sütunları var ve bu sadece pencereden benzersiz check out ateş
Michael

Kullanmak ON CONFLICT REPLACEistediğinize dikkat edin - yeni satırın eklenmesine izin vermek için önceden var olan satırları siler. Normalde, kısıtlama ihlalini ABORT veya ROLLBACK yapmak istiyorum. SQLite ON CONFLICT yan tümcesi
karmakaze

9

Sözdiziminiz eklediğiniz bağlantıyla eşleşmiyor; bu, aşağıdakileri belirtir:

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

Başlangıçta yaptım ... işe yaramadı. Her ihtimale karşı tekrar denedim ... hala çalışmıyor
Rich

1

Eklemede farklı sonuçlar alacağınız için tabloyu nasıl tanımladığınıza dikkat edin. Aşağıdakileri göz önünde bulundur



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> 

Ekleme / güncelleme efekti aynı olsa da id, tablo tanım türüne dayalı değişiklikler ('Alice'in şu anda sahip olduğu ikinci tabloya bakın id = 4; ilk tablo, beklediğimden daha fazlasını yapıyor, PRIMARY KEY'i aynı tutun ). Bu etkinin farkında olun.


1

Zaten bir tablonuz varsa ve herhangi bir nedenle yeniden oluşturmak istemiyorsanız / oluşturmak istemiyorsanız dizinleri kullanın :

CREATE UNIQUE INDEX my_index ON my_table(col_1, col_2);
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.