2009-10-28 17 views
2

Pour mon application, j'essaie d'ajouter des entrées sans avoir une entrée en double, et s'il y a un doublon notifier l'utilisateur et lui faire essayer à nouveau. En utilisant SQLite, que je connais très peu, j'ai essayé ces deux voies et je veux savoir lequel est le meilleur, le plus efficace ou le meilleur moyen de le développer?quelle instruction sqlite peut produire un résultat pour indiquer des entrées en double? Android

Première façon:

db.execSQL("INSERT INTO " + DatabaseHelper.DATABASE_TABLE + 
"(LATITUDE, LONGITUDE, RATING) SELECT " + latitude + ", " + longitude + ", " + rating + 
" WHERE NOT EXISTS (SELECT 1 FROM " + DatabaseHelper.DATABASE_TABLE + 
" WHERE LATITUDE = " + latitude + " AND LONGITUDE = " + longitude + ")"); 

Deuxième façon:

long id = -1; 
    try { 
     id = db.compileStatement(
       "SELECT COUNT(*) FROM " + DatabaseHelper.DATABASE_TABLE 
         + " WHERE LATITUDE = " + latitude 
         + " AND LONGITUDE = " + longitude) 
       .simpleQueryForLong(); 
    } catch (NullPointerException e) { 
     return -1; 
    } 
    return id; 

La première façon, soit des inserts ou ignore les valeurs, je vérifie ce faisant, le stockage de la ligne de comptage des lignes en une variable avant l'appel, appelez cette fonction, puis vérifiez ses résultats. Si les résultats ne sont pas plus élevés qu'avant l'appel, l'insertion a été ignorée et l'utilisateur reçoit le message 'values ​​exists'. (Très bâclée, je sais, mais les temps désespérés appelle des mesures désespérées)

La deuxième façon, renvoie le nombre réel de lignes qui correspondent aux numéros que je veux stocker, si le nombre retourné supérieur à 1, invite l'utilisateur avec le Le message "Valeurs existent".

J'ai fait des allers-retours en essayant différentes manières mais je ne sais pas comment configurer SQLite pour avoir des paires UNIQUES, ce qui m'a été dit être le plus facile. Si quelqu'un peut corriger l'une ou l'autre de ces façons et/ou les commenter, ce serait grandement apprécié.

Merci

Répondre

0

J'ai décidé d'aller avec mon deuxième approche (voir ci-dessus)

Raison étant depuis la création d'un UNIQUE INDEX semblent ne pas fonctionner pour moi et prov Ce fut une tâche difficile pour moi d'accomplir si cela était le résultat de ma fin ou celle de SQLite.

Son but n'est pas trivial, l'approche peut être élémentaire mais elle fait ce que j'ai besoin de faire. J'espère que les personnes rencontrant une situation comme celle-ci peuvent être influencées par les réponses laissées ici et souhaitent qu'elles aient plus de chance que moi.

3

Voici ce que je comprends que vous voulez: Pour avoir une table Database_Table (pas le nom le plus descriptif, si je puis dire) qui ne permettra jamais la même paire de latitude et de longitude à saisir deux lignes .

Si c'est correct, vous voulez déclarer une CLÉ PRIMAIRE ou UNIQUE qui incorpore les colonnes latitude et longitude. Si vous le faites, toute tentative d'INSERTION de la même paire lancera une exception, que vous pourrez attraper et ainsi informer l'utilisateur. En utilisant cette technique, vous n'aurez pas besoin d'utiliser la clause WHERE NOT EXISTS (...) dans votre requête, faites simplement un INSERT simple et laissez SQLite vous avertir d'une violation de votre contrainte UNIQUEness.

Si votre table existe déjà, la clé peut être facilement ajoutée à l'aide de la commande SQL CREATE INDEX. Puisque vous ne pouvez avoir qu'une seule PRIMARY KEY sur une table, si vous avez déjà une PRIMARY KEY sur la table, vous devrez utiliser une CLE UNIQUE à cette fin.

forme la plus simple de l'instruction CREATE INDEX vous utiliseriez est:

CREATE UNIQUE INDEX lat_long_unique ON Database_Table(latitude, longitude) 
+0

ma table n'est pas nommée Database_Table, c'est une constante de chaîne dans ma classe DatabaseHelper, et j'ai pensé à créer un index, mais j'ai quatre champs et je veux seulement deux d'entre eux, puis-je le faire par CREATE INDEX puis effectuez simplement un INSERT OU IGNORE simple? Et si tel est le cas, comment SQLite signalerait-il la contrainte UNIQUEness? Merci d'avance. –

+0

Je sais que je peux utiliser l'instruction INSERT OR IGNORE sur des champs s'ils sont uniques, ce qui est mon cas. Ma façon de dire si la valeur a été insérée ou ignorée est de stocker le nombre-de-lignes avant l'appel et de comparer après, des commentaires sur cela? –

+2

@Anthony: Vous créez l'index en incluant uniquement les deux champs que vous voulez être uniques. Vous n'avez pas besoin de compter les lignes et de comparer. Et n'utilisez pas OR IGNORE, utilisez ABORT (la valeur par défaut) ou ROLLBACK, selon la façon dont vous utilisez les transactions. En utilisant cette technique, vous exécutez une seule commande (INSERT) sur la base de données, en cherchant à voir si l'erreur SQLITE_CONSTRAINT est générée. Si c'est le cas, vous avez essayé (et échoué) d'insérer une ligne en double. –

1

Il me semble que l'aide d'un lat/long cru n'est pas un excellent moyen de vérifier les doublons. Chaque combinaison lat/long possible utilisant le format GeoPoint 1E6 d'Android couvre une zone de moins de cinq pouces carrés. Cette taille est, bien sûr, différente en fonction de l'endroit où vous vous trouvez sur Terre, mais elle est plutôt bonne. Donc vous devriez au moins arrondir votre lat/long au dix, cent ou mille le plus proche en fonction de la taille de la chose que vous voulez mesurer.

Avant de le stocker dans la base de données:

lat = (lat/1000)*1000; 
lon = (lon/1000)*1000; 

est ici un bon outil pour calculer les distances entre les points lat/long sur la Terre:

http://jan.ucc.nau.edu/~cvm/latlongdist.html