SQLite 테이블 제약 조건-여러 열에서 고유


179

SQLite 웹 사이트에서 구문 "차트"를 찾을 수 있지만 예제와 코드가 충돌하지 않습니다. 단일 열에 고유 제약 조건이있는 다른 테이블이 있지만 두 열의 테이블에 제약 조건을 추가하고 싶습니다. 이것이 내가 "구문 오류"메시지와 함께 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는 시작하기 전에 쉼표가 없습니다.
Majid Bashir

답변:


345

열 정의 섹션 내에 UNIQUE 선언을 넣으십시오. 작업 예 :

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

6
좋은 대답 +1. 이 구문을 사용하면 insertiteOnConflict가 아닌 일반 insert 메소드를 SQLiteDatabase.CONFLICT_REPLACE 플래그와 함께 사용할 수 있습니까?
Oleg Belousov

3
나는 ON CONFLICT IGNORE2 개 이상의 열로 (아직 교체 시도하지 않았 음)을 사용하고 있지만 고유 한 제약 조건을 준수하지는 않습니다. 중복 적으로 중복 항목을 추가합니다.
Michael

5
내가 NULL 열을 가지고 있기 때문에 분명히 그 유일한 창을 밖으로 촬영
마이클

ON CONFLICT REPLACE이를 사용 하면 원하는 것이 아닐 수 있습니다. 기존 행을 삭제하여 새 행을 삽입 할 수 있습니다. 일반적으로 제약 조건 위반을 ABORT 또는 ROLLBACK하고 싶습니다. SQLite ON CONFLICT 조항
카르마 카제

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하지만 테이블 정의 유형에 따라 변경됩니다 ( '앨리스'가있는 두 번째 테이블 참조 id = 4; 첫 번째 테이블은 내가 기대하는 것보다 더 많은 일을하고 있습니다. 기본 키를 동일하게 유지하십시오) ). 이 효과에 유의하십시오.


1

이미 테이블이 있고 어떤 이유로 든 테이블을 다시 만들거나 원하지 않는 경우 인덱스를 사용하십시오 .

CREATE UNIQUE INDEX my_index ON my_table(col_1, col_2);
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.