IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Android Discussion :

Requête sur plusieurs DB


Sujet :

Android

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    101
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 101
    Par défaut Requête sur plusieurs DB
    Bonjour,

    Je suis en train de développer une application qui a besoin de stocker en DB une partie des contacts de l'utilisateurs. J'ai choisi de ne stocker que les identifiants des contacts, le reste étant stocké dans les DBs d'Android.

    J'utilise la requête suivante pour récupérer le Curseur qui va bien :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT _id, display_name FROM view_contacts_restricted WHERE (contact_id IN (SELECT DISTINCT contact_id FROM dudes WHERE _id = 4));
    Et je reçois l'erreur suivante :
    ERROR/AndroidRuntime(272): Caused by: android.database.sqlite.SQLiteException: no such table: dudes

    J'ai vérifié, ma table existe bien, elle est juste dans ma BDD à moi, et pas celle d'Android qui contient les contacts. Je pense que le souci vient de là.

    Est-ce possible de corriger cette requête pour faire ce que je veux ? Ou dois je procéder en 2 temps ?

    Voici mon code actuel :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    String inString = SQLiteQueryBuilder.buildQueryString(true, DB_DUDE_TABLE, new String[] {KEY_CONTACT_ID}, KEY_BILL_ID + " = " + id, null, null, null, null); 
     
    Cursor cursor = mCtx.getContentResolver().query(uri, projection, Data.CONTACT_ID + " IN (" + inString + ")", null, null);
    Merci !

  2. #2
    Rédacteur
    Avatar de Viish
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2009
    Messages
    427
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2009
    Messages : 427
    Par défaut
    Bonsoir,

    Votre code tel qu'il est appelle effectivement la db d'Android.
    Pour pouvoir utiliser la votre, il vous faut créer une classe dans votre projet héritant de SQLiteOpenHelper et qui doit créer vos tables.
    Voici un extrait de la classe que j'utilise dans tous mes projets necessitants une base de données :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    public class SQLiteConnector extends SQLiteOpenHelper 
    {
    	private String locale;
     
    	public SQLiteConnector(Context context, String databaseName, int databaseVersion)
    	{
    		super(context, databaseName, null, databaseVersion);
    	}
     
    	public void onCreate(SQLiteDatabase db) 
    	{
    		creerTables();
    	}
     
    	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
    	{
    		db.execSQL("DROP TABLE IF EXISTS TABLE_NAME;");
    		creerTables();
    	}
     
    	private void creerTables (SQLiteDatabase db, boolean b)
    	{
    		db.execSQL("CREATE TABLE TABLE_NAME (_id NUMBER PRIMARY KEY NOT NULL)");
    		//...
    	}
    }
    Et voici comment je m'en sers.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    connector = new SQLiteConnector(context, DATABASE_NAME, DATABASE_VERSION);
    flux = connector.getWritableDatabase();
    //... Effectuez vos requêtes sur l'objet flux, dans votre cas
    String colonnes = {contact_id };
    Cursor c = stream.query("dudes", colonnes, "_id LIKE 4", null, null, null, null);
    En espérant que ceci vous aide à avancer.

    Bonne continuation.

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    101
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 101
    Par défaut
    Bonjour,

    Merci pour votre réponse. Le code que j'ai mis est effectivement dans une classe qui hérite de SQLiteOpenHelper, avec les méthodes de création de tables, d'insertion et d'update de données, ainsi que de récupération des données en base.

    En fait je me demande s'il est possible de faire une sorte de jointure entre ma DB et celle d'Android ou sont stockés les contacts. En fait je cherche à instancier des objets contacts (j'ai écrit une classe Contact pouvant stocker les infos qui m'intéressent) en partant de leurs identifiants (stockés dans ma DB) et en récupérant le reste des infos, stockées dans la DB Android...

    Voilà ma méthode en entier pour plus de clarté :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    public ArrayList<Contact> getDudes(long id) throws SQLException {
      ArrayList<Contact> dudes = new ArrayList<Contact>();
     
      Uri uri = ContactsContract.Contacts.CONTENT_URI;
      String[] projection = new String[] {
          ContactsContract.Contacts._ID,
          ContactsContract.Contacts.DISPLAY_NAME
      };
     
      String inString = SQLiteQueryBuilder.buildQueryString(true, DB_DUDE_TABLE, new String[] {KEY_CONTACT_ID}, KEY_BILL_ID + " = " + id, null, null, null, null); 
     
      Cursor cursor = mCtx.getContentResolver().query(uri, projection, Data.CONTACT_ID + " IN (" + inString + ")", null, null);
     
      if (cursor.moveToFirst()) {
        while (!cursor.isAfterLast()) {
          dudes.add(new Contact(cursor.getInt(0), cursor.getString(1)));
          cursor.moveToNext();
        }
      }
      return dudes;
    }
    P.S. pour le id = 4 c'est juste un cas particulier

  4. #4
    Expert confirmé

    Avatar de Feanorin
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    4 589
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 4 589
    Par défaut
    Bonjour,


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    String inString = SQLiteQueryBuilder.buildQueryString(true, DB_DUDE_TABLE, new String[] {KEY_CONTACT_ID}, KEY_BILL_ID + " = " + id, null, null, null, null);
    A cet endroit là tu demandes à avoir la requête avec les éléments que tu lui donnes .

    Mais a aucun moment tu lui donne l'accès a ta bd propre d'où l'erreur.

    Est-ce possible de corriger cette requête pour faire ce que je veux ? Ou dois je procéder en 2 temps ?
    tes Bds sont a deux endroits différents donc pour être propre cela serait plus évident de le faire en deux fois .

    Reprend l'exemple donnée par Viish pour déjà faire ta requête sur ta base de donnée. Ensuite quand tu obtiens le résultat, utilise le dans ta deuxième requête sur la base de donnée d'Android .

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    101
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 101
    Par défaut
    Effectivement, je comprend mieux mon erreur.

    J'ai résolu le problème en faisant une 1ère requête pour récupérer les id, et construire une String les contenant. Je donne ensuite cette string à la deuxième requete pour selectionner uniquement les contacts ayant ces id.

    Voilà ce que ça donne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    Cursor myCursor = mDb.query(DB_DUDE_TABLE, new String[] {KEY_CONTACT_ID}, KEY_BILL_ID + " = " + id, null, null, null, null);
    String inString = "";
    if (myCursor.moveToFirst()) {
      // Build inString
      while (!myCursor.isAfterLast()) {
        inString += "'" + myCursor.getLong(myCursor.getColumnIndex(KEY_CONTACT_ID)) + "'";
        if (!myCursor.isLast()) {
          inString += ", ";
        }
        myCursor.moveToNext();
      }
    }
     
    if (inString != "") {
      Cursor cursor = mCtx.getContentResolver().query(uri, projection, ContactsContract.Contacts._ID + " IN (" + inString + ")", null, null);
     
      if (cursor.moveToFirst()) {
        while (!cursor.isAfterLast()) {
          dudes.add(new Contact(cursor.getInt(0), cursor.getString(1)));
          cursor.moveToNext();
        }
      }
    }
    Cela semble fonctionner correctement, mais je me dis que ce bout de code n'est pas très élégant. Des idées d'améliorations ?

  6. #6
    Expert confirmé

    Avatar de Feanorin
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    4 589
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 4 589
    Par défaut
    Bonjour,

    Hmm , déjà créer deux fonctions

    Une qui retourne un boolean et le résultat sur la première requête.
    La seconde qui traite la deuxième requête avec le résultat en entrée .


    Après te renvoie déjà un boolean

    donc tu peux faire comme cela

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    do{
        inString += "'" +   myCursor.getLong(myCursor.getColumnIndex(KEY_CONTACT_ID)) + "'";
        if (!myCursor.isLast()) {
            inString += ", ";
        }
       while( myCursor.moveToNext());
    ça t'évite un test de plus.

    Comme pour le test myCursor.isLast() a toi de voir si tu veux le faire tout le temps dans la boucle ou plutôt supprimer la virgule quand tu sors de la boucle (ce qui ne fais qu'une opération au lieu de n opération dans ta boucle ). Mais après c'est plus lisible dans la boucle .

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Requête sur plusieurs tables
    Par sta_schmitt dans le forum Requêtes
    Réponses: 2
    Dernier message: 28/03/2006, 13h54
  2. Requéte sur plusieurs tables
    Par polux23 dans le forum Requêtes
    Réponses: 11
    Dernier message: 23/02/2006, 23h00
  3. [requête sur plusieurs bases]
    Par viny dans le forum Requêtes
    Réponses: 3
    Dernier message: 21/02/2006, 14h18
  4. Requête sur plusieurs bases de données
    Par Oluha dans le forum ASP
    Réponses: 8
    Dernier message: 14/10/2005, 14h57
  5. Requête sur plusieurs tables
    Par drinkmilk dans le forum Langage SQL
    Réponses: 8
    Dernier message: 11/07/2005, 12h25

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo