web-dev-qa-db-fra.com

Contrainte de table SQLite - unique sur plusieurs colonnes

Je peux trouver des "diagrammes" de syntaxe sur le site Web de SQLite, mais aucun exemple et mon code plante. J'ai d'autres tables avec des contraintes uniques sur une seule colonne, mais je veux ajouter une contrainte à la table sur deux colonnes. C'est ce que j'ai qui cause une SQLiteException avec le message "erreur de syntaxe".

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

Je le fais sur la base de ce qui suit:

contrainte de table

Pour être clair, la documentation sur le lien que j'ai fourni indique que CONTSTRAINT name devrait précéder ma définition de contrainte.

Quelque chose qui puisse conduire à la solution est que ce qui suit se plaint de ce qui suit mes définitions de colonnes entre parenthèses.

Si je mets

...last_column_name last_col_datatype) CONSTRAINT ...

l'erreur est près de "CONSTRAINT": erreur de syntaxe

Si je mets

...last_column_name last_col_datatype) UNIQUE ...

l'erreur est près de "UNIQUE": erreur de syntaxe

170
Rich

Placez la déclaration UNIQUE dans la section de définition de colonne:

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

Exemple de travail:

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

Eh bien, votre syntaxe ne correspond pas au lien que vous avez inclus, qui spécifie:

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

Faites attention à la manière dont vous définissez la table car vous obtiendrez des résultats différents lors de l'insertion. Considérer ce qui suit



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> 

Bien que l'effet insert/update soit le même, le id change en fonction du type de définition de table (voir le deuxième tableau où 'Alice' a maintenant id = 4; la première table fait plus de ce que je m'attends à faire, gardez la clé primaire identique). Soyez conscient de cet effet.

0
punkish